LCT复习题…
记得注意access()后面要不要splay()…
#include <cstdio>
#include <stack>
using namespace std;
const int N=100010;
int n,q;
int a[N];
struct nod{
int v,sum;
bool rev;
nod *pp,*pr,*ch[2];
}*NIL,poi[N];
struct LCT{
nod *root;
LCT(){
NIL=&poi[0];
for(int i=1;i<=n;i++){
poi[i].v=poi[i].sum=a[i];
poi[i].pp=poi[i].pr=poi[i].ch[0]=poi[i].ch[1]=NIL;
}
}
void update(nod *p){
p->sum=p->ch[0]->sum+p->ch[1]->sum+p->v;
}
void clear(nod *p){
if(!p->rev) return ;
nod *t=p->ch[0];p->ch[0]=p->ch[1];p->ch[1]=t;
p->ch[0]->rev^=1;p->ch[1]->rev^=1;p->rev=0;
}
void rotate(nod *x,bool t){
nod *y=x->pr,*z=y->pr,*b=x->ch[t^1];
b->pr=y;y->pr=x;x->pr=z;y->ch[t]=b;x->ch[t^1]=y;
if(z->ch[0]==y) z->ch[0]=x;
if(z->ch[1]==y) z->ch[1]=x;
update(y);update(x);
}
void splay(nod *x){
nod *r=x;
stack<nod*> stk;
while(r->pr!=NIL){
stk.push(r);
r=r->pr;
}
stk.push(r);
while(!stk.empty()){
clear(stk.top());
stk.pop();
}
while(x->pr!=NIL){
nod *y=x->pr,*z=y->pr;
if(z==NIL&&y->ch[0]==x) rotate(x,0);
else if(z==NIL&&y->ch[1]==x) rotate(x,1);
else if(z->ch[0]==y&&y->ch[0]==x){rotate(y,0);rotate(x,0);}
else if(z->ch[1]==y&&y->ch[1]==x){rotate(y,1);rotate(x,1);}
else if(y->ch[0]==x){rotate(x,0);rotate(x,1);}
else{rotate(x,1);rotate(x,0);}
}
x->pp=r->pp;
}
void access(nod *x){
for(nod *u=x,*v=NIL;u!=NIL;v=u,u=u->pp)
{splay(u);u->ch[1]->pp=u;u->ch[1]->pr=NIL;u->ch[1]=v;v->pr=u;update(u);}
}
void makeroot(nod *x){
access(x);splay(x);x->rev^=1;
}
bool check(nod *x,nod *y){
if(x==y) return 1;
access(x);access(y);splay(x);
if(x->pp!=NIL) return 1;
access(x);splay(y);
return y->pp!=NIL;
}
void link(nod *x,nod *y){
makeroot(x);x->pp=y;
}
void modify(nod *x,int v){
access(x);splay(x);x->v=v;update(x);
}
nod* lca(nod *x,nod *y){
access(x);access(y);
return x->pp==NIL?x:x->pp;
}
int getsum(nod *x,nod *y){
int sum=0;
nod *z=lca(x,y);
access(x);splay(z);sum+=z->ch[1]->sum;
access(y);splay(z);sum+=z->ch[1]->sum;
return sum+z->v;
}
};
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
LCT T;
scanf("%d",&q);
for(int i=1;i<=q;i++){
int a,b;
char s[1<<4];
scanf("%s%d%d",s,&a,&b);
if(s[0]=='b'){
if(T.check(&poi[a],&poi[b])) printf("no\n");
else{
printf("yes\n");
T.link(&poi[a],&poi[b]);
}
}
else if(s[0]=='p') T.modify(&poi[a],b);
else{
if(!T.check(&poi[a],&poi[b])) printf("impossible\n");
else printf("%d\n",T.getsum(&poi[a],&poi[b]));
}
}
return 0;
}