给定N个点以及每个点的权值,要你处理接下来的M个操作。
操作有4种。操作从0到3编号。点从1到N编号。
0:后接两个整数(x,y),代表询问从x到y的路径上的点的权值的xor和。
保证x到y是联通的。
1:后接两个整数(x,y),代表连接x到y,若x到Y已经联通则无需连接。
2:后接两个整数(x,y),代表删除边(x,y),不保证边(x,y)存在。
3:后接两个整数(x,y),代表将点X上的权值变成Y。
对于每一个0号操作,你须输出X到Y的路径上点权的Xor和。
#include<set> #include<map> #include<queue> #include<stack> #include<cmath> #include<cstdio> #include<vector> #include<bitset> #include<cstring> #include<iostream> #include<algorithm> using namespace std; int n,m; int x,y; int opt; int v[300010]; int f[300010]; int s[300010][2]; int st[300010]; int r[300010]; int sum[300010]; int get(int rt) { return rt==s[f[rt]][1]; } void pushup(int rt) { sum[rt]=v[rt]^sum[s[rt][0]]^sum[s[rt][1]]; } void pushdown(int rt) { if(r[rt]) { swap(s[rt][0],s[rt][1]); r[s[rt][0]]^=1; r[s[rt][1]]^=1; r[rt]^=1; } } int is_root(int rt) { return s[f[rt]][0]!=rt&&s[f[rt]][1]!=rt; } void rotate(int rt) { int fa=f[rt]; int anc=f[fa]; int k=get(rt); if(!is_root(fa)) { s[anc][fa==s[anc][1]]=rt; } s[fa][k]=s[rt][k^1]; f[s[fa][k]]=fa; s[rt][k^1]=fa; f[fa]=rt; f[rt]=anc; pushup(fa); pushup(rt); } void splay(int rt) { int top=0; st[++top]=rt; for(int i=rt;!is_root(i);i=f[i]) { st[++top]=f[i]; } for(int i=top;i>=1;i--) { pushdown(st[i]); } for(int fa;!is_root(rt);rotate(rt)) { if(!is_root(fa=f[rt])) { rotate(get(rt)==get(fa)?fa:rt); } } } void access(int rt) { for(int x=0;rt;x=rt,rt=f[rt]) { splay(rt); s[rt][1]=x; pushup(rt); } } void reverse(int rt) { access(rt); splay(rt); r[rt]^=1; } int find(int rt) { access(rt); splay(rt); while(s[rt][0]) { rt=s[rt][0]; } return rt; } void link(int x,int y) { reverse(x); f[x]=y; } void cut(int x,int y) { reverse(x); access(y); splay(y); if(s[x][1]||f[x]!=y||s[y][get(x)^1]) { return ; } s[y][0]=f[x]=0; } void change(int rt,int x) { v[rt]=x; access(rt); splay(rt); } int query(int x,int y) { reverse(x); access(y); splay(y); return sum[y]; } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { scanf("%d",&v[i]); } while(m--) { scanf("%d%d%d",&opt,&x,&y); if(opt==0) { printf("%d\n",query(x,y)); } else if(opt==1&&find(x)!=find(y)) { link(x,y); } else if(opt==2&&find(x)==find(y)) { cut(x,y); } else if(opt==3) { change(x,y); } } }
原文:https://www.cnblogs.com/Khada-Jhin/p/9744724.html