动态树裸题
练习模板
强大的缩行技术+异常sb的代码,LCT才99行 QAQ
#include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<queue> #include<set> #include<map> #include<vector> #include<algorithm> #include<iostream> #define T 303333 using namespace std; int sc() { int i=0; char c=getchar(); while(c>'9'||c<'0') c=getchar(); while(c>='0'&&c<='9') i=i*10+c-'0',c=getchar(); return i; } bool rev[T]; int ch[T][2],fa[T],val[T],st[T],v[T]; int n,m; bool Root(int x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;} void push_down(int x) { if(rev[x]) { rev[x]^=1;rev[ch[x][0]]^=1;rev[ch[x][1]]^=1; swap(ch[x][1],ch[x][0]); } } void push_up(int x) { val[x]=v[x]^val[ch[x][0]]^val[ch[x][1]]; } void rotate(int x) { int y=fa[x],z=fa[y],l,r; if(ch[y][0]==x)l=0;else l=1;r=l^1; if(!Root(y)) { if(ch[z][0]==y)ch[z][0]=x;else ch[z][1]=x; } fa[x]=z; fa[y]=x; fa[ch[x][r]]=y; ch[y][l]=ch[x][r]; ch[x][r]=y; push_up(y),push_up(x); } void splay(int x) { int top=0; st[++top]=x; for(int i=x;!Root(i);i=fa[i])st[++top]=fa[i]; while(top)push_down(st[top--]); while(!Root(x)) { int y=fa[x],z=fa[y]; if(!Root(y)) { if(ch[z][0]==y^ch[y][0]==x) rotate(x); else rotate(y); } rotate(x); } } void access(int x) { for(int t=0;x;t=x,x=fa[x])splay(x),ch[x][1]=t,push_up(x); } void make_root(int x){access(x),splay(x),rev[x]^=1;} void link(int x,int y){make_root(x),fa[x]=y;} void cut(int x,int y) { make_root(x),access(y),splay(y); if(ch[y][0]==x) ch[y][0]=fa[x]=0,push_up(y); } int find(int x) { access(x); splay(x); while(ch[x][0]) x=ch[x][0]; return x; } int query(int x,int y) { make_root(x);access(y);splay(y); return val[y]; } int main() { n=sc(),m=sc(); for(int i=1; i<=n; i++) v[i]=sc(); for(int i=1; i<=m; i++) { int c=sc(),a=sc(),b=sc(); if(c==0)printf("%d\n",query(a,b)); if(c==1){if(find(a)!=find(b))link(a,b);} if(c==2){if(find(a)==find(b))cut(a,b);} if(c==3)splay(a),v[a]=b,push_up(a); } return 0; }