void buildntree(int left ,int right){ int mid=(left+right)/2; tr[++cnt].l=left;tr[cnt].r=right; if (left!=right){ int t=cnt; tr[t].lc=cnt+1; buildntree(left,mid); tr[t].rc=cnt+1; buildntree(mid+1,right); }else { tr[cnt].fa=left; tr[cnt].size=1; } } int getfa(int po,int targ){ int mid=(tr[po].l+tr[po].r)/2; if (tr[po].l==tr[po].r) return(tr[po].fa); if (targ<=mid) return(getfa(tr[po].lc,targ)); else return(getfa(tr[po].rc,targ)); } int getsize(int po,int targ){ int mid=(tr[po].l+tr[po].r)/2; if (tr[po].l==tr[po].r) return(tr[po].size); if (targ<=mid) return(getsize(tr[po].lc,targ)); else return(getsize(tr[po].rc,targ)); } void expdfa(int targ,int cha){ tr[++cnt].l=tr[fol].l; tr[cnt].r=tr[fol].r; tr[cnt].fa=tr[fol].fa; tr[cnt].size=tr[fol].size; int mid=(tr[fol].l+tr[fol].r)/2; if (tr[fol].l==tr[fol].r){tr[cnt].fa=cha;return;} if (targ<=mid){ tr[cnt].rc=tr[fol].rc; fol=tr[fol].lc; tr[cnt].lc=cnt+1; expdfa(targ,cha); }else{ tr[cnt].lc=tr[fol].lc; fol=tr[fol].rc; tr[cnt].rc=cnt+1; expdfa(targ,cha); } } void expdsize(int targ){ tr[++cnt].l=tr[fol].l; tr[cnt].r=tr[fol].r; tr[cnt].fa=tr[fol].fa; tr[cnt].size=tr[fol].size; int mid=(tr[fol].l+tr[fol].r)/2; if (tr[fol].l==tr[fol].r){tr[cnt].size++;return;} if (targ<=mid){ tr[cnt].rc=tr[fol].rc; fol=tr[fol].lc; tr[cnt].lc=cnt+1; expdsize(targ); }else{ tr[cnt].lc=tr[fol].lc; fol=tr[fol].rc; tr[cnt].rc=cnt+1; expdsize(targ); } } int fax=getfa(dl[top].root,op[i][1]), fay=getfa(dl[top].root,op[i][2]); while (getfa(dl[top].root,fax)!=fax) fax=getfa(dl[top].root,fax); while (getfa(dl[top].root,fay)!=fay) fay=getfa(dl[top].root,fay); if (fax!=fay){ dl[top+1].root=cnt+1; dl[top+1].ans=dl[top].ans+i; dl[top+1].sid=dl[top].sid+1; int sizx=getsize(dl[top].root,fax); int sizy=getsize(dl[top].root,fay); fol=dl[top].root; if (sizx<sizy) expdfa(fax,fay); if (sizx>=sizy) expdfa(fay,fax); if (sizx==sizy){int t=cnt+1;fol=dl[top+1].root;expdsize(fax);dl[top+1].root=t;} top++;} else{dl[top+1].root=dl[top].root; dl[top+1].ans=dl[top].ans; dl[top+1].sid=dl[top].sid; top++;};