好久没写lct了
居然还能一发过
#include<cstdio> #include<iostream> const int maxn = 100100; int n,q; int son[maxn][2],fa[maxn],val[maxn],sum[maxn],tag[maxn]; inline int get(int x,int p=1){return son[fa[x]][p]==x;} inline int is_root(int x){return !(get(x,0)||get(x));} inline void up(int x){sum[x]=sum[son[x][0]]+sum[son[x][1]]+val[x];} inline void down(int x){ if(tag[x]){ tag[son[x][0]]^=1,tag[son[x][1]]^=1; tag[x]=0,std::swap(son[x][0],son[x][1]); } } inline void rotate(int x){ int y=fa[x],z=fa[y],b=get(x); if(!is_root(y))son[z][get(y)]=x; son[y][b]=son[x][!b],son[x][!b]=y; fa[son[y][b]]=y,fa[y]=x,fa[x]=z; up(y),up(x); } int st[maxn],top; inline void splay(int x){ st[top=1]=x; for(int y=x;!is_root(y);st[++top]=y=fa[y]); for(;top;--top)down(st[top]); for(;!is_root(x);rotate(x)) if(!is_root(fa[x]))rotate(get(x)^get(fa[x])?x:fa[x]); up(x); } inline void access(int x){ for(int t=0;x;son[x][1]=t,t=x,x=fa[x]) splay(x); } inline void make_root(int x){ access(x),splay(x),tag[x]^=1; } inline int con(int x,int y){ make_root(x),access(y),splay(y); int now=x;while(fa[now])now=fa[now]; return now==y; } inline void link(int x,int y){ make_root(x),fa[x]=y; } inline int split(int x,int y){ make_root(x),access(y),splay(y); return sum[y]; } int main(){ std::ios::sync_with_stdio(false),std::cin.tie(0); std::cin >> n; for(int i=1;i<=n;++i)std::cin >> val[i],sum[i]=val[i]; char buf[20]; std::cin >> q; for(int i=1;i<=q;++i){ int a,b; std::cin >> buf >> a >> b; if(*buf == 'b'){ if(con(a,b))std::cout << "no "; else std::cout << "yes ",link(a,b); } if(*buf == 'p'){ make_root(a),val[a]=b,up(a); } if(*buf == 'e'){ if(!con(a,b))std::cout << "impossible "; else std::cout << split(a,b) << ' '; } } }