LCT。模板还是不熟啊。
#include<iostream> #include<cstdio> #include<cstring> #define maxv 30050 using namespace std; int n,w[maxv],val[maxv],tree[maxv][3],fath[maxv],stack[maxv],cnt=0,a,b,q,rev[maxv]; char type[20]; bool isroot(int x) { return (tree[fath[x]][1]!=x) && (tree[fath[x]][2]!=x); } void pushup(int x) { int ls=tree[x][1],rs=tree[x][2]; val[x]=val[ls]+val[rs]+w[x]; } void pushdown(int x) { if (rev[x]) { int ls=tree[x][1],rs=tree[x][2]; rev[x]=0;rev[ls]^=1;rev[rs]^=1; swap(tree[x][1],tree[x][2]); } } void rotate(int x) { int y=fath[x],z=fath[y],l,r; if (tree[y][1]==x) l=1;else l=2; r=3-l; if (!isroot(y)) { if (tree[z][1]==y) tree[z][1]=x; else tree[z][2]=x; } fath[x]=z;fath[y]=x;fath[tree[x][r]]=y; tree[y][l]=tree[x][r];tree[x][r]=y; pushup(y);pushup(x); } void splay(int x) { int y=fath[x],z=fath[y]; cnt=0;stack[++cnt]=x; for (int i=x;!isroot(i);i=fath[i]) stack[++cnt]=fath[i]; for (int i=cnt;i>=1;i--) pushdown(stack[i]); while (!isroot(x)) { int y=fath[x],z=fath[y]; if (!isroot(y)) { if ((tree[y][1]==x)^(tree[z][1]==y)) rotate(x); else rotate(y); } rotate(x); } } void access(int x) { int regis=0; while (x) { splay(x);tree[x][2]=regis; pushup(x);regis=x;x=fath[x]; } } void makeroot(int x) { access(x);splay(x);rev[x]^=1; } void link(int x,int y) { makeroot(x); fath[x]=y; } int find(int x) { access(x);splay(x); int y=x; while (tree[y][1]) y=tree[y][1]; return y; } int split(int x,int y) { makeroot(x);access(y);splay(y); return val[y]; } void work1() { scanf("%d%d",&a,&b); if (find(a)!=find(b)) { printf("yes "); link(a,b); } else printf("no "); } void work2() { scanf("%d%d",&a,&b); access(a);splay(a); w[a]=b;pushup(a); } void work3() { scanf("%d%d",&a,&b); if (find(a)!=find(b)) printf("impossible "); else printf("%d ",split(a,b)); } int main() { scanf("%d",&n); for (int i=1;i<=n;i++) { scanf("%d",&w[i]); val[i]=w[i]; } scanf("%d",&q); for (int i=1;i<=q;i++) { scanf("%s",type); if (type[0]=='b') work1(); else if (type[0]=='p') work2(); else work3(); } return 0; }