bzoj2843
三个操作:1、连接x,y
2、把x的值改为y
3、查询x到y这条路径上的所以数的和
没有cut的lct…
ps:真的想打自己(再见 各种笔误
#include <cstdio>
#include <algorithm>
using namespace std;
#define N 33000
int n,m,a[N],ans[N],fa[N],ch[N][2],rev[N];
char str[10];
bool isroot(int x){return x!=ch[fa[x]][0] && x!=ch[fa[x]][1];}
void update(int x){ans[x]=a[x]+ans[ch[x][0]]+ans[ch[x][1]];}
void pushdown(int x){
if(!rev[x]) return ;
rev[ch[x][0]]^=1;rev[ch[x][1]]^=1;rev[x]^=1;
swap(ch[x][0],ch[x][1]);
}
void push(int x){
if(!isroot(x)) push(fa[x]);
pushdown(x);
}
void rotate(int x){
int y=fa[x],z=fa[y],t=ch[y][0]==x;
if(!isroot(y)) ch[z][ch[z][1]==y]=x;
fa[y]=x;fa[x]=z;fa[ch[x][t]]=y;
ch[y][t^1]=ch[x][t];ch[x][t]=y;
update(y);update(x);
}
void splay(int x){
push(x);
while(!isroot(x)){
int y=fa[x];
if(isroot(y)){rotate(x);return;}
if(ch[y][0]==x^ch[fa[y]][0]==y) rotate(x);
else rotate(y);rotate(x);
}
}
void access(int x){
int y=0;
while(x){
splay(x);ch[x][1]=y;update(x);
y=x;x=fa[x];
}
}
void makeroot(int x){
access(x);splay(x);rev[x]^=1;
}
int find(int x){
access(x);splay(x);
while(ch[x][0]) x=ch[x][0];
return x;
}
void link(int x,int y){
if(find(x)==find(y)){printf("no\n");return;}
makeroot(x);fa[x]=y;printf("yes\n");
}
void change(int x,int y){
splay(x);a[x]=y;update(x);
}
void query(int x,int y){
if(find(x)!=find(y)){printf("impossible\n");return;}
makeroot(x);access(y);splay(y);printf("%d\n",ans[y]);
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]),ans[i]=a[i];
scanf("%d",&m);
for(int i=1;i<=m;i++){
int x,y;scanf("%s%d%d",str,&x,&y);
if(str[0]=='b') link(x,y);
else if(str[0]=='p') change(x,y);
else query(x,y);
}
return 0;
}