Codeforces Round 858 (Div. 2)

A - Walking Master

明显需要移动至同一斜列处,实现即可

#include <iostream>

using namespace std;
 
void solve(){
	int a,b,c,d;
	cin >> a >> b >> c >> d;
	if(a==c&&b==d) {
		cout << 0 << endl;
		return ;
	}
	if(b>d){
		cout << "-1" << endl;
		return;
	} 
	if(b==d&&(a>=c)) {
		cout << a-c << endl;
		return ;
	}
	int ans=(d-b);
	if(a<(c-(d-b))){
		cout << "-1" << endl;
		return;
	}
	ans+=(a-(c-(d-b)));
	cout << ans << endl;
}

signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0); 
	int t;
	cin >> t;
	while(t--){
		solve();
	}
	
	return 0;
} 

B - Mex Master

可讨论,我们发现,结果只有可能是 0 , 1 , 2
因为如果没有若干个 1 ,和若干个其他数,我们将 1 排成一部分然后再将其他的排开,边界上的值一定大于 2
如果我们发现,将所有的 0 和其他数字插空摆,不会有连续的 0 出现,就可以使 MEX=0
同时,如果有至少一个数大于 1 ,则我们用这个数把 0 和其他数隔开就可以使 MEX=1

#include <iostream>
#include <algorithm>
#include <string.h>
#define int long long 

using namespace std;
const int maxN=2*1e5+10;
int a[maxN],n,ts[maxN];
void solved(){
	cin >> n ;
	memset(ts,0,sizeof(ts));
	memset(a,-1,sizeof(a));
	for(int i=1;i<=n;++i) cin >> a[i],ts[a[i]]++;
	sort(a+1,a+n+1);
	if(!ts[0]){
		cout << 0 << endl;
		return ;
	}
	int k=1;
	while(a[k]==0&&k<=n) ++k;
	if(k>n) cout << 1 << endl;
	else {
		int p1=k-1,p2=n-k+1;
		if(p1-1<=p2) cout << 0 << endl;
		else {
			if(a[k]!=1) cout << 1 << endl;
			else {
				int p=k;
				while(a[p]==1&&p<=n)++p;
				if(p>n) cout << 2 << endl;
				else {
					cout << 1 << endl;
				}
			}
		}
	}
}

signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0); 
	int t;
	cin >> t;
	while(t--){
		solved();
	}
	return 0;
} 

C - Sequence Master

本次比赛最令人窒息的题目之一
为什么要放在这个位置啊?

打表发现规律,然后再枚举情况就可以了
规律懒得写了,其他题解里也有

#include <iostream>
#include <math.h>

#define int long long
using namespace std;
const int maxN=4*1e5+10;
int t,n,a[maxN];

signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0); 
	cin >> t;
	while(t--){
		cin >> n;
		n*=2;
		for(int i=1;i<=n;++i) cin >> a[i];
		int ans=0;
		for(int i=1;i<=n;++i) ans+=abs(a[i])*1ll;
		if(n==2) {
		    
		    cout << abs(a[1]-a[2])*1ll << endl;
		    continue;
		}
		else if(n==4){
			int s=0;
			for(int i=1;i<=n;++i) s+=abs(a[i]-2)*1ll;
			ans=min(s,ans);
		}
		//cout << ans << endl;
		if(n%4==0){
			int s=0;
			for(int i=1;i<=n;++i) s+=abs(a[i]+1)*1ll;
			for(int i=1;i<=n;++i) ans=min(ans,s-abs(a[i]+1)*1ll+abs(a[i]-n/2)*1ll);
		}
		cout << ans << endl;
	}
	
	return 0;
} 

D - DSU Master

不会,连题都读不懂

E - Tree Master

根号分治

如果我们对节点数小于 n 的层数的每一对节点进行预处理,对于每一个树上的节点来说,其只可能与其同层的节点匹配,而每一层的节点数都小于 n,所以复杂度是 O(nn)

对于不进行预处理的点来说,其层节点数一定大于 n,因此其最多跳 n 层就必定遇见一个层节点数小于 n 的,复杂度 O(nn)

本题有树分块做法,但介于我不大会,所以等一等再写

#include <iostream>
#include <vector>
#define int long long

using namespace std;
const int maxN=1e5+10,B=500; 
int n,q; 
int fa[maxN],f[maxN][B];//这里前面用真实的标号,后面用同一层中的标号 
int dep[maxN],cnt[maxN],id[maxN],a[maxN];
vector<int> g[maxN];

void dfs(int now,int dp){
	id[now]=++cnt[dp],dep[now]=dp;
	for(int x:g[now])
		dfs(x,dp+1);
}

int query(int x,int y){
	if(!x&&!y) return 0;
	if(cnt[dep[x]]<B&&f[x][id[y]])
		return f[x][id[y]];
	int ans=query(fa[x],fa[y])+(a[x]*a[y]);
	if(cnt[dep[x]]<B) f[x][id[y]]=f[y][id[x]]=ans;
	return ans;
}

signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0),cout.tie(0); 
	cin >> n >> q;
	//a[0]=0;
	for(int i=1;i<=n;++i) cin >> a[i];
	for(int i=2;i<=n;++i) cin >> fa[i],g[fa[i]].push_back(i);
	dfs(1,0);
	while(q--){
		int x,y;
		cin >> x>> y;
		cout << query(x,y) << endl;
		
	}
	return 0;
} 
posted @   颈流推进  阅读(28)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· Apache Tomcat RCE漏洞复现(CVE-2025-24813)
点击右上角即可分享
微信分享提示