http://www.lydsy.com/JudgeOnline/problem.php?id=1180
大约又是个裸的lct,开始re了好久后来发现建了重边
#include<cstdio> #include<iostream> const int maxn =60007; int n,m; int top=0; int ch[maxn][2],fa[maxn],stack[maxn]; int ans[maxn],v[maxn]; bool rev[maxn]; inline int read() { int x=0; char c=getchar(); while(c<'0'||c>'9') c=getchar(); while(c<='9'&&c>='0') x=x*10+c-'0',c=getchar(); return x; } void update(int x) { ans[x]=ans[ch[x][1]]+ans[ch[x][0]]+v[x]; } bool isroot(int x) { return ch[fa[x]][1]!=x&&ch[fa[x]][0]!=x; } void pushdown(int x) { if(rev[x]) { rev[x]^=1; rev[ch[x][0]]^=1;rev[ch[x][1]]^=1;std::swap(ch[x][1],ch[x][0]); } } void rotate(int x) { int y=fa[x],z=fa[y],d=(ch[y][1]==x)^1; if(!isroot(y)) ch[z][ch[z][1]==y]=x; fa[x]=z; ch[y][d^1]=ch[x][d],fa[ch[x][d]]=y; ch[x][d]=y;fa[y]=x; update(y);update(x); } void splay(int x) { stack[++top]=x; for(int i=x;!isroot(i);i=fa[i]) stack[++top]=fa[i]; while(top)pushdown(stack[top--]); while(!isroot(x)) { int y=fa[x],z=fa[y]; if(!isroot(y)) { if(ch[y][1]==x^ch[z][1]==y)rotate(x); else rotate(y); } rotate(x); } return ; } void access(int x) { for(int i=0;x;i=x,x=fa[x]) { splay(x); ch[x][1]=i;update(x); } } void makeroot(int x) { access(x),splay(x);rev[x]^=1; } void link(int x,int y) { makeroot(x),fa[x]=y;return splay(x); } int find(int x) { for(access(x),splay(x);ch[x][0];x=ch[x][0]) ; return x; } void split(int x,int y) { makeroot(x),access(y); return splay(y); } int query(int x,int y) { split(x,y);return ans[y]; } void modify(int x,int y) { access(x),splay(x),v[x]=y; return update(x); } int main() { n=read(); for(int i=1;i<=n;++i) { v[i]=read();ans[i]=v[i]; } m=read(); char c[70]; for(int a,b;m;m--) { scanf("%s",c),a=read(),b=read(); if(c[0]=='b') { if(find(a)==find(b))puts("no"); else puts("yes"),link(a,b); } else if(c[0]=='p') { modify(a,b); } else { if(find(a)!=find(b))puts("impossible"); else printf("%d\n",query(a,b)); } } return 0; }