【题解】
这道题其实有个树状数组维护dfs序的做法,不过懒得想那么多直接写了Link-Cut Tree
1 #include<cstdio> 2 #include<algorithm> 3 #define N 600010 4 #define rg register 5 #define ls (c[u][0]) 6 #define rs (c[u][1]) 7 using namespace std; 8 int n,m,x,y,top,val[N],c[N][2],fa[N],sum[N],st[N],rev[N]; 9 char opt[50]; 10 inline int read(){ 11 int k=0,f=1; char c=getchar(); 12 while(c<'0'||c>'9')c=='-'&&(f=-1),c=getchar(); 13 while('0'<=c&&c<='9')k=k*10+c-'0',c=getchar(); 14 return k*f; 15 } 16 inline bool isroot(int u){ 17 return c[fa[u]][0]!=u&&c[fa[u]][1]!=u; 18 } 19 inline bool which(int u){ 20 return c[fa[u]][1]==u; 21 } 22 inline void pushup(int u){ 23 sum[u]=sum[ls]+sum[rs]+val[u]; 24 } 25 inline void pushdown(int u){ 26 if(rev[u]) rev[ls]^=1,rev[rs]^=1,rev[u]=0,swap(ls,rs); 27 } 28 void rotate(int u){ 29 int f=fa[u],gf=fa[f],wh=which(u); 30 if(!isroot(f)) c[gf][which(f)]=u; 31 fa[u]=gf; fa[f]=u; fa[c[u][wh^1]]=f; 32 c[f][wh]=c[u][wh^1]; c[u][wh^1]=f; 33 pushup(f); pushup(u); 34 } 35 void splay(int u){ 36 st[top=1]=u; 37 for(rg int i=u;!isroot(i);i=fa[i]) st[++top]=fa[i]; 38 for(rg int i=top;i;i--) pushdown(st[i]); 39 while(!isroot(u)){ 40 if(!isroot(fa[u])) rotate(which(u)==which(fa[u])?fa[u]:u); 41 rotate(u); 42 } 43 } 44 void access(int u){ 45 for(rg int son=0;u;son=u,u=fa[u]) splay(u),c[u][1]=son,pushup(u); 46 } 47 void makeroot(int u){ 48 access(u); splay(u); rev[u]^=1; 49 } 50 int find(int u){ 51 access(u); splay(u); 52 while(ls) u=ls; return u; 53 } 54 void split(int x,int y){ 55 makeroot(x); access(y); splay(y); 56 } 57 void cut(int x,int y){ 58 split(x,y); 59 if(c[y][0]==x) c[y][0]=0,fa[x]=0; 60 } 61 void link(int x,int y){ 62 makeroot(x); fa[x]=y; 63 } 64 int main(){ 65 n=read(); 66 for(rg int i=1;i<=n;i++) val[i]=sum[i]=read(); 67 m=read(); 68 while(m--){ 69 scanf("%s",opt+1); x=read(); y=read(); 70 if(opt[1]=='b'){ 71 if(find(x)==find(y)) puts("no"); 72 else{ 73 puts("yes"); 74 link(x,y); 75 } 76 } 77 if(opt[1]=='p'){ 78 access(x); splay(x); val[x]=y; pushup(x); 79 } 80 if(opt[1]=='e'){ 81 if(find(x)!=find(y)) puts("impossible"); 82 else{ 83 split(x,y); 84 printf("%d ",sum[y]); 85 } 86 } 87 } 88 return 0; 89 }