Link-Cut-Tree

来源:互联网 发布:知乎 边牧犬舍 北京 编辑:程序博客网 时间:2024/06/06 05:26
#include<bits/stdc++.h>#define MAXN 30030using namespace std;inline int rd(){int x=0,y=1;char c=getchar();while(c<'0' || c>'9'){if(c=='-')y=-y;c=getchar();}while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar();return x*y;}int n,m;int son[MAXN][2],fa[MAXN],sz[MAXN],mx[MAXN],sum[MAXN],stk[MAXN],nxt[MAXN],val[MAXN];bool rev[MAXN];inline bool isroot(int x){return son[fa[x]][0]!=x&&son[fa[x]][1]!=x;}inline bool is_right(int x){return son[fa[x]][1]==x;}inline void pushup(int x){mx[x]=sum[x]=val[x];sz[x]=sz[son[x][0]]+sz[son[x][1]]+1;mx[x]=max(mx[x],max(mx[son[x][0]],mx[son[x][1]]));sum[x]+=sum[son[x][0]]+sum[son[x][1]];}inline void pushdown(int x){if(rev[x]){rev[x]^=1,rev[son[x][0]]^=1,rev[son[x][1]]^=1;swap(son[x][0],son[x][1]);}}inline void Rotate(int x){int f=fa[x],ff=fa[f],which=is_right(x);if(!isroot(f))son[ff][son[ff][1]==f]=x;son[f][which]=son[x][which^1];fa[son[f][which]]=f;fa[f]=x;son[x][which^1]=f;fa[x]=ff;pushup(f);pushup(x);}inline void splay(int x){int tot=0;stk[++tot]=x;for(int i=x; !isroot(i); i=fa[i])stk[++tot]=fa[i];for(int i=tot; i>0; i--)pushdown(stk[i]);while(!isroot(x)){int f=fa[x];if(!isroot(f))Rotate((is_right(x)==is_right(f)?f:x));Rotate(x);}}inline void access(int x){int t=0;while(x){splay(x);son[x][1]=t;pushup(x);t=x;x=fa[x];}}inline void toroot(int x){access(x);splay(x);rev[x]^=1;}inline void link(int x,int y){toroot(x);fa[x]=y;splay(x);}inline void cut(int x,int y){toroot(x);access(y);splay(y);son[y][0]=fa[x]=0;}inline int Find(int x){access(x);splay(x);while(son[x][0])x=son[x][0];return x;}map<int,int>mp[MAXN];int main(){n=rd(),m=rd();for(int i=1; i<=n; i++){val[i]=sum[i]=mx[i]=rd();sz[i]=1;}char op[40];while(m--){scanf("%s",op);int x=rd(),y=rd();if(op[0]=='U'){access(x);splay(x);val[x]=y;pushup(x);}else if(op[0]=='L'){if(Find(x)==Find(y))puts("NO");else puts("YES"),link(x,y),mp[x][y]=mp[y][x]=1;}else if(op[0]=='C'){if(mp[x][y])puts("YES"),cut(x,y),mp[x][y]=mp[y][x]=0;else puts("NO");}else if(op[0]=='M'){if(Find(x)!=Find(y))puts("-1");else{toroot(x);access(y);splay(y);printf("%d\n",mx[y]);}}else{if(Find(x)!=Find(y))puts("-1");else{toroot(x);access(y);splay(y);printf("%d\n",sum[y]);}}}return 0;}

原创粉丝点击