2023 江西省赛 【9.26训练补题】

Dashboard - 2023 (ICPC) Jiangxi Provincial Contest -- Official Contest - Codeforces

2023年江西省ICPC省赛部分题解_NIT最帅的博客-CSDN博客 

I. Tree

*考虑异或性质,一个数异或两次相当于不变

*快读

错解:建树更新深度

#include<bits/stdc++.h>
using namespace std;
const int N=5e5+5;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pi;
const ll mod=1e9+7;

int n,q,x,y,op,w;
int fa[N];
int v[N];
int d[N];
map<pi,int>mp;
vector<int>edge[N];
void getd(int x,int de){
	d[x]=de;
	for(auto i:edge[x]){
		if(i!=fa[x]){
			fa[i]=x;
			v[i]=mp[{i,x}];
			getd(i,de+1);
		}
	}
}
void solve1(int x,int y,int w){
	if(x==y)return;
	if(d[x]>d[y]){
		v[x]^=w;
		solve1(fa[x],y,w);
	}
	else if(d[x]<d[y]){
		v[y]^=w;
		solve1(x,fa[y],w);
	}
	else {
		v[x]^=w,v[y]^=w;
		solve1(fa[x],fa[y],w);
	}
}
void solve2(int x){
	//printf("x%d\n",x);
	int res=0;
	for(auto i:edge[x]){
		if(i!=fa[x])res^=v[i];
		//printf("res%lld i%d\n",res,i);
	}res^=v[x];
		
	//if(x!=1)res^=fa[x];
	printf("%d\n",res);
}
int main(){
	scanf("%d%d",&n,&q);
	for(int i=1;i<n;i++){
		scanf("%d%d%d",&x,&y,&w);
		//v[{x,y}]=w;
		//if(x>y)swap(x,y);
		edge[x].push_back(y);
		edge[y].push_back(x);
		//fa[y]=x,v[y]=w;
		mp[{x,y}]=w;
		mp[{y,x}]=w;
	}fa[1]=-1;
	getd(1,1);
	//for(int i=1;i<=n;i++)printf("i%d d%d\n",i,d[i]);
	while(q--){
		scanf("%d",&op);
		if(op==1){
			scanf("%d%d%d",&x,&y,&w);
			if(w==0)continue;
			solve1(x,y,w);
		}else{
			scanf("%d",&x);
			solve2(x);
		}
	}
	return 0;
}

 正解:直接记录每个点周围边的异或值,op1只改变x,y两个点

#include<bits/stdc++.h>
using namespace std;
const int N=5e5+5;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pi;
const int inf=1<<30;
const ll mod=1e9+7;
inline void read(int &x){
	int f=1;
	x=0;
	char ch=getchar();
	while(ch<'0'||'9'<ch){
		if(ch=='-')f=-1;
		ch=getchar();
	}while('0'<=ch&&ch<='9'){
		x=(x<<3)+(x<<1)+(ch&15);
		ch=getchar();
	}x*=f;
}
int n,q,x,y,op,w;
int ans[N];

int main(){
	read(n);read(q); 
	for(int i=1;i<n;i++){
		read(x);read(y);read(w);
		ans[x]^=w;ans[y]^=w;
	}
	while(q--){
		read(op);
		if(op==1){
			read(x);read(y);read(w);
			if(w==0)continue;
			ans[x]^=w,ans[y]^=w;
		}else{
			read(x);
			printf("%d\n",ans[x]);
		}
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值