首页 > 其他分享 >CFR-844-Div-1-2解题报告

CFR-844-Div-1-2解题报告

时间:2023-03-01 16:02:45浏览次数:75  
标签:tmp 844 int tt ++ ind Div 矩形 CFR

比赛传送门

A. Parallel Projection

题意:有一个 \(w\times d\times h\) 的长方体,顶面和底面有两个点,只能走直线且不能穿过长方体,求最短距离。

显然曼哈顿距离必须要走。多出来绕弯的距离一定是选一个点,到边缘的最短距离 \(\times 2\)。

By cxm1024

#include<bits/stdc++.h>
using namespace std;
signed main() {
	int t;
	cin>>t;
	while(t-->0) {
		int x,y,z,a,b,c,d;
		cin>>x>>y>>z>>a>>b>>c>>d;
		cout<<z+abs(a-c)+abs(b-d)+min({a,b,c,d,x-a,x-c,y-b,y-d})*2<<endl;
	}
	return 0;
}

B. Going to the Cinema

题意:有 \(n\) 个人,每人有一个要求 \(a_i\),表示他愿意去电影院当且仅当其他人中有至少 \(a_i\) 个去。问全部满足要求的方案数。

首先对 \(a\) 从小到大排序,枚举总共去几个人。假设去 \(x\) 个人,则一定是 \(a_i\) 最小的 \(x\) 个人去。考虑第 \(x\) 个人是否愿意去,以及第 \(x+1\) 个人是否愿意不去即可。

By IceYukino

int T,n,a[N];
signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	cin>>T;
	while(T--){
		cin>>n;
		for(int i=1;i<=n;i++) cin>>a[i];
		sort(a+1,a+n+1);
		int ans=1;
		if(a[1]!=0) ans++;
		for(int i=1;i<n;i++){
			if(a[i]>i-1||a[i+1]<=i) continue;
			ans++;
		}
		cout<<ans<<endl;
	}
	return 0;
}

C. Equal Frequencies

给你一个小写字母字符串,求更改字母的方案,使得让所有出现过的字母的出现次数都相同,且次数尽可能少。

可以枚举需要总共出现几个字母,进而得到每个字母的出现次数 \(x\)。对于每个次数超过 \(x\) 的字母需要砍掉多余的改成其他字母;对于次数不超过 \(x\) 的字母,需要将一些填成 \(x\),一些砍掉。显然让出现尽可能多的字母填成 \(x\) 最优。

By cxm1024

#include<bits/stdc++.h>
using namespace std;
struct node{
	int val,num;
} tt[26];
int cnt[26];
signed main() {
	int t;
	cin>>t;
	while(t--) {
		memset(tt,0,sizeof(tt));
		memset(cnt,0,sizeof(cnt));
		int n;
		string s;
		cin>>n>>s;
		for(int i=0;i<n;i++)
			tt[s[i]-'a'].val++;
		for(int i=0;i<26;i++)
			tt[i].num=i;
		sort(tt,tt+26,[](node p,node q) {
			return p.val<q.val;
		});
		int minx=1e9,mini;
		for(int i=1;i<=26;i++) {
			if(n%i!=0) continue;
			int x=n/i,sum=0,ans=0;
			for(int j=25;j>=0;j--) {
				if(tt[j].val>x) sum+=tt[j].val-x,ans+=tt[j].val-x;
				else if(26-j<=i) ans+=x-tt[j].val;
				else ans+=tt[j].val;
			}
			if(ans<minx) minx=ans,mini=i;
		}
		int x=n/mini;
		for(int j=25;j>=0;j--) {
			if(tt[j].val>x) cnt[tt[j].num]=x-tt[j].val;
			else if(26-j<=mini) cnt[tt[j].num]=x-tt[j].val;
			else cnt[tt[j].num]=-tt[j].val;
		}
		vector<int> add;
		for(int j=0;j<26;j++)
			while(cnt[j]>0) add.push_back(j),cnt[j]--;
		for(int i=0;i<n;i++)
			if(cnt[s[i]-'a']<0)
				cnt[s[i]-'a']++,s[i]=add.back()+'a',add.pop_back();
		cout<<minx/2<<endl<<s<<endl;
	}
	return 0;
}

D. Many Perfect Squares

题意:有一个不重复的正整数数组 \(a\),你需要找到一个 \(x\),使得每个元素加上 \(x\) 后出现尽可能多的完全平方数。

显然答案至少为 \(1\)。如果答案超过 \(2\),可以枚举钦定两个变成完全平方数的数 \(p,q(p<q)\),则有 \(a^2=p+x,b^2=q+x\),得出 \(b^2-a^2=q-p\),即 \((b+a)(b-a)=q-p\)。对 \(q-p\) 枚举因数,求得 \(a,b\),进而得到 \(x\),即可算出此时的完全平方数个数。

By IceYukino

int T,n,a[N];
signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	cin>>T;
	while(T--){
		cin>>n;
		for(int i=1;i<=n;i++) cin>>a[i];
		int mx=1;
		for(int i=1;i<=n;i++)
			for(int j=i+1;j<=n;j++){
				int del=a[j]-a[i];
				for(int k=1;k<=sqrt(del);k++){
					if(del%k!=0) continue;
					int c=k,b=del/k;
					if((c+b)%2==1) continue;
					int tmp=(c+b)/2,y=(c-b)/2;
					if(tmp*tmp>=a[j]&&y*y>=a[i]&&tmp*tmp-a[j]==y*y-a[i]){
						int x=tmp*tmp-a[j],sum=0;
						for(int l=1;l<=n;l++){
							int u=a[l]+x;
							int oo=sqrt(u);
							if(oo*oo==u) sum++;
						}
						mx=max(mx,sum);
					}
				}
			}
		cout<<mx<<endl;
	}
	return 0;
}

有一个优化的技巧,当找到一个确定的 \(x\) 时,不立刻计算数量更新答案,而是存起来,到最后去重后再计算。由于同一个 \(x\) 可能会被多对不同的元素、因数找到,所以优化非常显著。

By noimi

int main() {
	TEST {
		INT(n);
		VEC(ll, a, n);
		vl cand;
		rep(i, n) rep(j, i + 1, n) {
			ll d = a[j] - a[i];
			fore(l, divisor(d)) {
				ll r = d / l;
				if(l > r) continue;
				if((l + r) & 1) continue;
				ll x = (r - l) / 2, y = (r + l) / 2;
				// dump(l, r, x, y, d);
				cand.eb(x * x - a[i]);
			}
		}
		ll ans = 1;
		// rep(i, 0, 100) cand.eb(i);
		fore(e, cand) {
			if(e < 0) continue;
			int now = 0;
			fore(x, a) {
				ll t = x + e;
				ll s = sqrtl(t);
				if(s * s == t) now++;
			}
			// if(now == 2) dump(e);
			chmax(ans, now);
		}
		OUT(ans);
	}
}

枚举因数的过程同样可以通过分解质因数,用 DFS 合并来实现。首先存下每个质因数以及次数,DFS 合并时依此搜索每个质因数,枚举该质因数选几次,进入下一个质因数搜索。由于一个质因数的次数不同,因数就不同,所以一定不重不漏。

By 18Michael

inline void init()
{
	for(int i=2;i<=Mx;++i)
	{
		if(!u[i])p[++p_t]=i;
		for(int j=1;j<=p_t && p[j]*i<=Mx;++j)
		{
			u[p[j]*i]=1;
			if(!(i%p[j]))break;
		}
	}
	//printf("%d\n",p_t);
}
inline void solve(int x)
{
	//printf("  solve %d\n",x);
	int w=Z/x;
	if((x^w)&1)return ;
	/*a+b=w
	b-a=x*/
	LL A=(w-x)/2,X=A*A-tmp,y,z;
	if(X<0)return ;
	res=0;
	for(int i=1;i<=n;++i)
	{
		y=X+a[i];
		z=sqrt(y);
		res+=(z*z==y);
	}
	//printf(" X:%lld res:%d\n",X,res);
	ans=max(ans,res);
}
inline void dfs(int x,int y)
{
	//printf(" dfs %d %d\n",x,y);
	if(y>Z/y)return ;
	if(x>t)return solve(y);
	for(int j=0;j<=num[x];++j)
	{
		dfs(x+1,y);
		y*=val[x];
	}
}
inline void calc(int x,int y)
{
	//printf("calc %d %d\n",x,y);
	Z=a[y]-a[x];
	int z=Z;
	tmp=a[x],t=0;
	for(int i=1;i<=p_t && p[i]*p[i]<=z;++i)if(!(z%p[i]))
	{
		val[++t]=p[i],num[t]=0;
		for(;!(z%p[i]);z/=p[i])++num[t];
	}
	//printf("t:%d\n",t);
	if(z>1)val[++t]=z,num[t]=1;
	//printf("t:%d\n",t);
	//for(int i=1;i<=t;++i)printf("(%d,%d)",val[i],num[i]);
	//puts("");
	dfs(1,1);
}
int main()
{
	init(),read(Test_num);
	while(Test_num--)
	{
		read(n),ans=1;
		for(int i=1;i<=n;++i)read(a[i]);
		for(int i=1;i<=n;++i)for(int j=i+1;j<=n;++j)calc(i,j);
		printf("%d\n",ans);
	}
	return 0;
}

E. Rectangle Shrinking

题意:在一个 \(2\times 10^9\) 的网格中,放置了 \(n\) 个矩形。对于每个矩形,你可以删掉也可以用一个子矩形代替。要求最后不能有矩形重叠,且面积尽可能大。

做法一

一个简单的猜测为,最终面积即为面积并,考虑如何构造。我们采用在线添加的方式,每次添加一个新矩形时保持矩面积为矩形面积并且不重叠。矩形用三个 set 动态维护,分别表示跨两行、只第一行和只第二行。这样 set 内只需要存矩形的左右边界和标号。

考虑添加的矩形有哪些情况:如果有被新矩形覆盖的,直接删掉;如果新矩形被某个旧矩形覆盖,直接不考虑新矩形。否则,情况一定只有矩形交而不存在矩形覆盖。具体实现上,对新矩形的行数分类讨论:

假设新矩形为一行,先处理与一行矩形的冲突:新覆盖旧则删掉,旧覆盖新则跳过,出现相交则把新矩形缩短到不相交。结束后,如果新矩形被缩到没有了(\(l>r\)),同样直接跳过。接下来处理与两行矩形的冲突:旧覆盖新同样跳过,但新不能完全覆盖旧(行数不够)。如果新在区间上覆盖了旧(即覆盖了旧的其中一行),则将旧的被覆盖的一行删掉,两行矩形改为一行矩形。如果新和旧只相交不包含,则将新矩形缩短到不相交即可。

假设新矩形为两行,先处理与两行矩形的冲突,与1-1冲突相同。接着处理与一行矩形的冲突:新覆盖旧则删掉,旧覆盖新的一整行时,将新矩形改为一行矩形,转到一行矩形处理方式。如果只相交不包含,则将旧的一行矩形缩短到不相交。

By cxm1024

#include<bits/stdc++.h>
using namespace std;
struct node {
	mutable int l,r,num;
	bool operator<(const node &o) const {
		return r<o.r;
	}
};
struct vv {
	int u,l,d,r;
} ans[200010];
signed main() {
	int t;
	cin>>t;
	while(t--) {
		set<node> s[3];
		int n;
		cin>>n;
		for(int i=1;i<=n;i++)
			ans[i]={0,0,0,0};
		for(int i=1;i<=n;i++) {
			int u,l,d,r;
			cin>>u>>l>>d>>r;
			if(u==d) {
				auto tmp=s[u].lower_bound({l,l,0});
				bool flag=1;
				while(tmp!=s[u].end()) {
					if(tmp->l<=l&&tmp->r>=r) {
						flag=0;
						break;
					}
					if(tmp->l>=l&&tmp->r<=r)
						tmp=s[u].erase(tmp);
					else if(tmp->l>r) break;
					else if(tmp->l<l) l=tmp->r+1,tmp++;
					else if(tmp->r>r) r=tmp->l-1,tmp++;
				}
				if(l>r||flag==0) continue;
				auto tt=s[0].lower_bound({l,l,0});
				while(tt!=s[0].end()) {
					if(tt->l<=l&&tt->r>=r) {
						flag=0;
						break;
					}
					if(tt->l>=l&&tt->r<=r) {
						s[3-u].insert({tt->l,tt->r,tt->num});
						tt=s[0].erase(tt);
					}
					else if(tt->l>r) break;
					else if(tt->l<l) l=tt->r+1,tt++;
					else if(tt->r>r) r=tt->l-1,tt++;
				}
				if(l>r||flag==0) continue;
				s[u].insert({l,r,i});
			}
			else {
				auto tmp=s[0].lower_bound({l,l,0});
				bool flag=1;
				while(tmp!=s[0].end()) {
					if(tmp->l<=l&&tmp->r>=r) {
						flag=0;
						break;
					}
					if(tmp->l>=l&&tmp->r<=r)
						tmp=s[0].erase(tmp);
					else if(tmp->l>r) break;
					else if(tmp->l<l) l=tmp->r+1,tmp++;
					else if(tmp->r>r) r=tmp->l-1,tmp++;
				}
				if(l>r||flag==0) continue;
				for(int x=1;x<=2;x++) {
					if(u==d) {
						auto tt=s[u].lower_bound({l,l,0});
						bool flg=1;
						while(tt!=s[u].end()) {
							if(tt->l<=l&&tt->r>=r) {
								flg=0;
								break;
							}
							if(tt->l>=l&&tt->r<=r)
								tt=s[u].erase(tt);
							else if(tt->l>r) break;
							else if(tt->l<l) l=tt->r+1,tt++;
							else if(tt->r>r) r=tt->l-1,tt++;
						}
						if(r<l||flg==0) flag=0;
						continue;
					}
					auto tt=s[x].lower_bound({l,l,0});
					while(tt!=s[x].end()) {
						if(tt->l<=l&&tt->r>=r) {
							u=d=3-x;
							break;
						}
						if(tt->l>=l&&tt->r<=r)
							tt=s[x].erase(tt);
						else if(tt->l>r) break;
						else if(tt->l<l) {
							int ll=tt->l,rr=l-1,num=tt->num;
							tt=s[x].erase(tt);
							if(rr>=ll) {
								s[x].insert({ll,rr,num});
								tt=s[x].upper_bound({ll,rr,num});
							}
						}
						else if(tt->r>r) {
							tt->l=r+1;
							if(tt->l>tt->r) tt=s[x].erase(tt);
							else tt++;
						}
					}
				}
				if(l<=r&&flag) {
					if(u==d) s[u].insert({l,r,i});
					else s[0].insert({l,r,i});
				}
			}
		}
		int tot=0;
		for(auto [l,r,num]:s[0])
			ans[num]={1,l,2,r},tot+=(r-l+1)*2;
		for(auto [l,r,num]:s[1])
			ans[num]={1,l,1,r},tot+=r-l+1;
		for(auto [l,r,num]:s[2])
			ans[num]={2,l,2,r},tot+=r-l+1;
		cout<<tot<<endl;
		for(int i=1;i<=n;i++)
			cout<<ans[i].u<<" "<<ans[i].l<<" "<<ans[i].d<<" "<<ans[i].r<<endl;
	}
	return 0;
}

做法二

将矩形离线下来,按左端点排序,依次添加每个矩形,同时维护两行分别能到达的最右端点。由于添加一个矩形时,之前的矩形左端点都不超过当前矩形的左端点,所以只要最右端点超过当前矩形的右端点,则一定被包含。如果当前矩形的某一整行都被包含,则删掉该行,删空则跳过本矩形;如果当前矩形的左端点比两行最优端点的较小值还要小,则改为较小值 \(+1\),这样,新矩形和原来的图形最多有一行重叠,将重叠的那一行的旧矩形缩短即可。

By KrK

#include <bits/stdc++.h>
using namespace std;

typedef pair <int, int> ii;

const int Maxn = 200005;

struct rec {
	int u, l, d, r;
};

int T;
int n;
rec R[Maxn];
int seq[Maxn];
ii reach[2];

bool Less(const int &a, const int &b)
{
	return R[a].l < R[b].l;
}

int main()
{
	scanf("%d", &T);
	while (T--) {
		scanf("%d", &n);
		for (int i = 0; i < n; i++) {
			scanf("%d %d %d %d", &R[i].u, &R[i].l, &R[i].d, &R[i].r);
			R[i].u--; R[i].d--;
			seq[i] = i;
		}
		sort(seq, seq + n, Less);
		reach[0] = reach[1] = ii(0, -1);
		for (int z = 0; z < n; z++) {
			int ind = seq[z];
			int mn = min(reach[0].first, reach[1].first);
			R[ind].l = max(R[ind].l, mn + 1);
			if (R[ind].l > R[ind].r) continue;
			if (reach[R[ind].u].first >= R[ind].r)
				R[ind].u++;
			if (R[ind].u > R[ind].d) continue;
			if (reach[R[ind].d].first >= R[ind].r)
				R[ind].d--;
			if (R[ind].u > R[ind].d) continue;
			for (int h = R[ind].u; h <= R[ind].d; h++) {
				if (reach[h].first >= R[ind].l)
					R[reach[h].second].r = R[ind].l - 1;
				reach[h] = ii(R[ind].r, ind);
			}
		}
		int res = 0;
		for (int i = 0; i < n; i++)
			if (R[i].u > R[i].d || R[i].l > R[i].r) {
				R[i].u = R[i].d = -1;
				R[i].l = R[i].r = 0;
			} else res += (R[i].d - R[i].u + 1) * (R[i].r - R[i].l + 1);
		printf("%d\n", res);
		for (int z = 0; z < n; z++)
			printf("%d %d %d %d\n", R[z].u + 1, R[z].l, R[z].d + 1, R[z].r);
	}
	return 0;
}

做法三

我们发现,一行和一行的冲突非常容易计算,两行和两行的冲突和很容易算,复杂的是一行和两行的部分,有较多分类讨论。于是考虑将第三种转化为第一种。

首先同样将所有矩形分成三类,每一类内部可以很方便地处理到不重叠。然后将两行的矩形拆成第一行的一个矩形和第二行的一个矩形,重新处理新的第一行和新的第二行。由于之前每类内部都处理完了,新第一行和第二行的冲突全部为一行矩形和“原两行矩形”的冲突。如果一个包含了另一个,则直接将被包含的删掉:如果删掉的为原两行矩形,则等价于把两行矩形缩成一行矩形。否则则为相交且不包含,由于原两行矩形不方便缩短(需要考虑另一行),所以我们要求让原一行矩形缩短即可。

这种做法虽然在代码实现上较做法二稍长,但分类讨论极少,不容易写错。

By orzdevinwang

#include<bits/stdc++.h>
#define L(i, j, k) for(int i = (j); i <= (k); ++i)
#define R(i, j, k) for(int i = (j); i >= (k); --i)
#define ll long long
#define sz(a) ((int) (a).size())
#define vi vector < int >
#define me(a, x) memset(a, x, sizeof(a))
#define ull unsigned long long
#define ld __float128
using namespace std;
const int N = 1e6 + 7;
int n, u[N], d[N], l[N], r[N];
bool vis[N];
vector < int > S[3];
void solve(vi &a, int rp = -1) {
	sort(a.begin(), a.end(), [&] (int x, int y) {
		return r[x] == r[y] ? l[x] > l[y] : r[x] < r[y];
	});
	vi b;
	for(auto x : a) {
		while(sz(b) && l[b.back()] >= l[x]) {
			if(rp == -1) vis[b.back()] = false;
			else if(rp == 0) ++u[b.back()];
			else assert(rp == 1), --d[b.back()];
			b.pop_back();
		}
		if(sz(b) && r[b.back()] >= l[x]) {
			int y = b.back();
			int lenx = d[x] - u[x] + 1;
			int leny = d[y] - u[y] + 1;
			if(leny <= lenx) r[y] = l[x] - 1;
			else l[x] = r[y] + 1;
		}
		b.emplace_back(x);
	}
	a = b;
}
void Main() {
	cin >> n;
	S[0].clear();
	S[1].clear();
	S[2].clear();
	L(i, 1, n) {
		cin >> u[i] >> l[i] >> d[i] >> r[i];
		vis[i] = true;
		int op = -1;
		if(u[i] == 1 && d[i] == 1) op = 0;
		if(u[i] == 2 && d[i] == 2) op = 1;
		if(u[i] == 1 && d[i] == 2) op = 2;
		assert(op != -1);
		S[op].emplace_back(i);
	}
	L(i, 0, 2) solve(S[i]);
	for(auto u : S[2]) L(i, 0, 1) S[i].emplace_back(u);
	L(i, 0, 1) solve(S[i], i);

	int sumsz = 0;
	L(i, 1, n) if(vis[i]) {
		int siz = (d[i] - u[i] + 1) * (r[i] - l[i] + 1);
		if(siz < 0) {
			cout << "jingya\n";
			assert(false);
		}
		if(!siz) vis[i] = false;
		sumsz += siz;
	}
	cout << sumsz << '\n';
	L(i, 1, n)
		if(vis[i]) cout << u[i] << ' ' << l[i] << ' ' << d[i] << ' ' << r[i] << '\n';
		else cout << 0 << ' ' << 0 << ' ' << 0 << ' ' << 0 << '\n';
}
int main() {
	ios :: sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	int t;
	cin >> t;
	while(t--) Main();
	return 0;
}

做法四

思路与做法三类似,但实现上更为巧妙。

考虑开两个 set 分别维护第一行的矩形和第二行的矩形。实现一个“插入矩形”函数,仅支持插入一个一行的矩形,且产生冲突时优先缩短新矩形而让旧矩形不变(包含则正常删除)。这可以用 set 很轻松地实现。

与做法三相同,在两行矩形与一行矩形产生冲突时,应优先更改一行矩形,对应在这里,则为先插入所有两行矩形再插入所有一行矩形。对于两行矩形,只需要将其拆成两个一行矩形插入,该插入函数自然会正确处理冲突。然后依次插入一行矩形即可。统计答案时要注意两行矩形如果有一行被包含、删除了,则改为一行矩形输出。

By yuto1115

template<class T>
class range_set {
    using iterator = typename set<tuple<T, T, int>>::iterator;

    set<tuple<T, T, int>> st;

    // return the least range which intersects with [x, inf)
    iterator least_intersecting_range(T x) {
        auto it = st.lower_bound({x, x, -1});
        if (it == st.begin() or ::get<1>(*prev(it)) <= x) return it;
        return prev(it);
    }

public:
    range_set() {}

    set<tuple<T, T, int>> get() { return st; }

    void insert(T l, T r, int id) {
        assert(l < r);
        auto it = least_intersecting_range(l);
        if (it != st.end() and ::get < 0 > (*it) < l) {
            auto [nl, nr, _] = *it;
            if (nr >= r) return;
            l = nr;
            ++it;
        }
        while (it != st.end() and ::get < 1 > (*it) <= r) {
            it = st.erase(it);
        }
        if (it != st.end() and ::get < 0 > (*it) < r) {
            auto [nl, nr, _] = *it;
            r = nl;
        }
        assert(l <= r);
        if (l == r) return;
        st.insert({l, r, id});
    }

    template<class U>
    friend ostream &operator<<(ostream &, const range_set<U> &);
};

template<class T>
ostream &operator<<(ostream &os, const range_set<T> &st) { return os << st.st; }

void solve() {
    INT(n);
    vi u(n), l(n), d(n), r(n);
    rep(i, n) scan(u[i], l[i], d[i], r[i]);
    vector<range_set<int>> st(2);
    rep(i, n) {
        if (u[i] == 1 and d[i] == 2) {
            st[0].insert(l[i], r[i] + 1, i);
        }
    }
    st[1] = st[0];
    rep(i, n) {
        if (u[i] == 1 and d[i] == 1) {
            st[0].insert(l[i], r[i] + 1, i);
        }
    }
    rep(i, n) {
        if (u[i] == 2 and d[i] == 2) {
            st[1].insert(l[i], r[i] + 1, i);
        }
    }
    vi nu(n, 3), nl(n), nd(n), nr(n);
    int ans = 0;
    for (auto [L, R, i]: st[0].get()) {
        chmin(nu[i], 1);
        chmax(nd[i], 1);
        ans += R - L;
        nl[i] = L;
        nr[i] = R - 1;
    }
    for (auto [L, R, i]: st[1].get()) {
        chmin(nu[i], 2);
        chmax(nd[i], 2);
        ans += R - L;
        nl[i] = L;
        nr[i] = R - 1;
    }
    print(ans);
    rep(i, n) {
        if (nu[i] == 3) nu[i] = 0;
        print(nu[i], nl[i], nd[i], nr[i]);
    }
}

int main() {
    int t;
    cin >> t;
    rep(i, t) solve();
}

标签:tmp,844,int,tt,++,ind,Div,矩形,CFR
From: https://www.cnblogs.com/cxm1024/p/17168433.html

相关文章

  • CFR-745-Div-2解题报告
    没打比赛,赛后做出3道。这场比赛题目质量很高,非常巧妙。A.CQXYMCountPermutations\(Problem\)求有多少\(2n\)的排列满足存在超过\(n\)个\(i\)使得\(p_i<p_{i+......
  • CFR-746-Div-2解题报告
    VP做出来一道,补题又做出来3道。A.GamerHemose\(Problem\)你有\(n\)个武器,要打一个体力为\(H\)的敌人,第\(i\)个武器可以对敌人造成\(a_i\)的伤害,每把武器不能......
  • CFR-109解题报告
    A.Hometask题意:一个字符串,给定\(k\)个限制字符对\((a_i,b_i)\),要求从原串中删除尽可能少的字符,使得不存在一个相邻的限制字符对。保证\(a_i\neb_i\),且每个字符最多......
  • CFR-744-Div-3解题报告
    赛时AC2道题,掉大分(哭)A.Casimir'sStringSolitaire题目传送门\(Problem\)给你一个仅含A,B,C的字符串,每次可以删掉一个A和一个B,或一个B和一个C,位置、顺序不......
  • CFR-840-Div-2解题报告
    比赛传送门C.AnotherArrayProblem题意:给你一个数组\(a\),每次可以选两个位置\(i,j(i<j)\),将\([i,j]\)内的所有数替换为\(|a_i-a_j|\)。问最终数组的和最大为多少......
  • CFR-843-Div-2解题报告
    比赛传送门C.InterestingSequence题意:给你\(n,x\),求最小的\(m\gen\),使\(n\&(n+1)\&(n+2)\&\cdots\&m=x\),或判断无解。首先每一位独立,分别考虑。与运算每一位都......
  • CFR-850-Div-1解题报告
    比赛传送门A.Monsters(easyversion)题意:有\(n\)个怪物,每个有\(a_i\)滴血,每次可以选择一个怪物减一滴血,也可以“让所有怪物减一滴血,且如果杀死怪物则重复操作”。......
  • EDU-CFR-115-Div-2解题报告
    赛时AC3道,补题做出来一道A.ComputerGame\(Problem\)有一个\(2\timesn\)的01矩阵,1为障碍,你要从\((1,1)\)走到\((2,n)\),每一步只能向右、上、下、右上、右下走,问......
  • EDU-CFR-116-Div-2解题报告
    比赛传送门做出来五道题。A.ABBalance{%noteinfono-iconproblem%}给你一个只含有a和b的字符串,问怎样通过修改尽可能少的字符,使得ab的数量和ba的数量相......
  • EDU-CFR-138解题报告
    比赛传送门A.CowardlyRooks题意:有一个\(n\timesn\)的棋盘,有\(m\)个位置上有车,保证互不攻击。问是否能将一个车移动一次使得仍然互不攻击。稍加思考可得,如果\(......