//By SiriusRen #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N=200050; int n,q,cnt,dfn[N],last[N],tree[N*16],lson[N*16],rson[N*16]; int first[N],next[N],v[N],w[N],tot,root[N],fa[N],deep[N],f[N]; struct Node{int xx,yy;char op[2];}node[N]; void dfs(int x){ dfn[x]=++cnt; for(int i=first[x];~i;i=next[i]) if(v[i]!=fa[x])deep[v[i]]=deep[x]+1,fa[v[i]]=x,dfs(v[i]); last[x]=cnt; } void add(int x,int y){v[tot]=y,next[tot]=first[x],first[x]=tot++;} void Add(int x,int y){add(x,y),add(y,x);} void insert(int l,int r,int &pos,int num,int wei){ if(!pos)pos=++cnt; if(l==r){tree[pos]=wei;return;} int mid=(l+r)>>1; if(mid<num)insert(mid+1,r,rson[pos],num,wei); else insert(l,mid,lson[pos],num,wei); tree[pos]=tree[lson[pos]]+tree[rson[pos]]; } int query(int l,int r,int pos,int L,int R){ if(!pos)return 0; if(l>=L&&r<=R)return tree[pos]; int mid=(l+r)>>1; if(mid<L)return query(mid+1,r,rson[pos],L,R); else if(mid>=R)return query(l,mid,lson[pos],L,R); else return query(l,mid,lson[pos],L,R)+query(mid+1,r,rson[pos],L,R); } void merge(int pos1,int &pos2){ if(!pos2)pos2=++cnt; tree[pos2]+=tree[pos1]; // printf("pos1=%d pos2=%d lson[pos1]=%d rson[pos1]=%d tree[pos]=%d ",pos1,pos2,lson[pos1],rson[pos1],tree[pos2]); if(lson[pos1])merge(lson[pos1],lson[pos2]); if(rson[pos1])merge(rson[pos1],rson[pos2]); } int find(int x){return x==f[x]?x:f[x]=find(f[x]);} void dfs2(int x){ if(lson[x])dfs2(lson[x]); if(rson[x])dfs2(rson[x]); } int main(){ memset(first,-1,sizeof(first)); scanf("%d%d",&n,&q),getchar(); for(int i=1;i<=q;i++){ scanf("%s%d%d",node[i].op,&node[i].xx,&node[i].yy); if(node[i].op[0]=='A')Add(node[i].xx,node[i].yy); } for(int i=1;i<=n;i++)if(!fa[i])dfs(i); cnt=0; for(int i=1;i<=n;i++)insert(1,n,root[i],dfn[i],1),f[i]=i; for(int i=1;i<=q;i++){ if(node[i].op[0]=='A'){ int fx=find(node[i].xx),fy=find(node[i].yy); if(fx!=fy)merge(root[fx],root[fy]),f[fx]=fy; } else{ if(deep[node[i].xx]>deep[node[i].yy])swap(node[i].xx,node[i].yy); int fy=find(node[i].yy); long long temp=query(1,n,root[fy],dfn[node[i].yy],last[node[i].yy]); printf("%lld ",(tree[root[fy]]-temp)*temp); } } }
//By SiriusRen #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N=100050; int n,m,xx,yy,fa[N],ch[N][2],rev[N],size[N],Size[N],q[N],top; char op[10]; bool isroot(int x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;} void push_up(int x){size[x]=size[ch[x][0]]+size[ch[x][1]]+1+Size[x];} void push_down(int x){if(rev[x])rev[ch[x][0]]^=1,rev[ch[x][1]]^=1,swap(ch[x][0],ch[x][1]),rev[x]=0;} void rotate(int p){ int q=fa[p],y=fa[q],x=(ch[q][1]==p); ch[q][x]=ch[p][!x],fa[ch[q][x]]=q; ch[p][!x]=q,fa[p]=y; if(!isroot(q)){ if(ch[y][1]==q)ch[y][1]=p; if(ch[y][0]==q)ch[y][0]=p; }fa[q]=p,push_up(q); } void splay(int x){ q[++top]=x; for(int i=x;!isroot(i);i=fa[i])q[++top]=fa[i]; while(top)push_down(q[top]),top--; for(int y=fa[x];!isroot(x);rotate(x),y=fa[x])if(!isroot(y)){ if((ch[fa[y]][0]==y)^(ch[y][0]==x))rotate(x); else rotate(y); }push_up(x); } void access(int x){for(int t=0;x;t=x,x=fa[x])splay(x),Size[x]+=size[ch[x][1]]-size[t],ch[x][1]=t,push_up(x);} void makeroot(int x){access(x),splay(x),rev[x]^=1;} void link(int x,int y){makeroot(x),makeroot(y),fa[x]=y,Size[y]+=size[x],push_up(y);} void split(int x,int y){makeroot(x),access(y),splay(x);} int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=n;i++)size[i]=1; while(m--){ scanf("%s%d%d",op,&xx,&yy); if(op[0]=='A')link(xx,yy); else split(xx,yy),printf("%lld ",1ll*(Size[yy]+1)*(size[xx]-Size[yy]-1)); } }