Codeforces Round 969 (Div. 2)

ab题没啥好说的,b题一开始看题错成线段树了,后面发现维护最大值就过了(我就说b怎么会有线段树)。。。

C:Dora and C++

卡的我死死的,好久没卡c了,数论果然是最短板。。。我有两个推论,但是一个都不会用:

1.翡蜀定理。(但是这题只有正数)(处理两个数的情况)

2.断环为链。(但是我只会n方,即以每个点为起点,把其他点都排在他后面)(处理只有一个数的情况)

正解是这样:

  1. 确实是翡蜀定理,因为对\(a_i\)减去一个数相当于对其余数加上一个数

  2. 断环为链只需要把第一个节点放到最后去,并不需要重新维护整个链

把上述两个结论结合我们就可以用\(gcd(a,b)\)一个数去处理所有节点了,结束。

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;

int a[maxn];
signed main() {
	int t; cin >> t;
	while (t--) {
		int n,x,y;
		cin>>n>>x>>y;
		x=__gcd(x,y);
		for(int i=1;i<=n;i++)cin>>a[i];
		sort(a+1,a+n+1);
		if(x==1){
			cout<<0<<"\n";
			continue;
		}
		for(int i=1;i<n;i++){
			int tmp=(a[n]-a[i])/x;
			a[i]+=tmp*x;
		}
		sort(a+1,a+n+1);
		int mx=a[n];int ans=0x3f3f3f3f;
		for(int i=1;i<=n;i++){
			ans=min(ans,mx-a[i]);
			mx=a[i]+x;
		}
		cout<<ans<<"\n";
	}
}

D:

观察出性质即结束。
性质:根节点和叶子节点值相同时叶子节点权为0,否则为1;
所以根节点不是?时可直接求答案。
否则,如果cnt0和cnt1相等,先填根的人一定不优。

#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;
vector<int>E[maxn];
bool vis[maxn];
void dfs(int u,int fa){
	if(E[u].size()==1&&E[u][0]==fa){
		vis[u]=1;
		//cout<<u<<"mk\n";
		return;
	}
	for(int i:E[u])	if(i!=fa)dfs(i,u);
}
signed main() {
	ios::sync_with_stdio(false);
	// 解除cin和cout的默认绑定,来降低IO的负担使效率提升
	cin.tie(NULL); cout.tie(NULL);
	int t; cin >> t;
	while (t--) {
		int n;cin>>n;
		for(int i=1;i<=n;i++)if(vis[i])vis[i]=0;
		for(int i=1;i<=n;i++)E[i].clear();
		for(int i=1;i<n;i++){
			int u,v;
			cin>>u>>v;
			E[u].push_back(v);
			E[v].push_back(u);
		}
		dfs(1,0);
		string s;cin>>s;
		int cnt1=0,cnt0=0,cnt=0,cnt2=0;
		int ans=0;
		for(int i=1;i<n;i++){
			if(vis[i+1]){
				if(s[i]=='?')cnt++;
				else if(s[i]=='1')cnt1++;
				else cnt0++;
			}
			else if(s[i]=='?')cnt2++;
		}
		//cout<<cnt0<<cnt1<<cnt<<cnt2<<"\n";
		if(s[0]=='?'){
			int fir=cnt/2,sec=(cnt+1)/2;
			if(cnt1==cnt0){
				if(cnt2%2)ans=cnt1+sec;
				else ans=cnt1+fir;
			}
			else if(cnt1>cnt0){
				ans=cnt1+fir;
			}
			else{
				ans=cnt0+fir;
			}
		}
		else{
			int sec=cnt/2,fir=(cnt+1)/2;
			int v0=s[0]-'0';
			if(v0){
				ans=cnt0+fir;
			}
			else{
				ans=cnt1+fir;
			}
		}
		cout<<ans<<"\n";
	}
}
posted @ 2024-08-31 22:00  lyrrr  阅读(134)  评论(0)    收藏  举报