bzoj3673: 可持久化并查集 by zky&&3674: 可持久化并查集加强版
主席树可持久化数组,还挺好YY的
然而加强版要路径压缩。。
发现压了都RE
结果看了看数据,默默的把让fx的父亲变成fy反过来让fy的父亲变成fx
搞笑啊
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; int n; struct chairman_tree { int lc,rc,c; }tr[1300000];int trlen,rt[410000]; int maketree(int now,int l,int r,int p,int k) { if(now==0)now=++trlen; tr[now].lc=tr[now].rc=0; tr[now].c=-1; if(l==r)tr[now].c=k; else { int mid=(l+r)/2; if(p<=mid)tr[now].lc=maketree(tr[now].lc,l,mid,p,k); else tr[now].rc=maketree(tr[now].rc,mid+1,r,p,k); } return now; } int merge(int x,int y) { if(x==0||y==0)return x+y; tr[x].lc=merge(tr[x].lc,tr[y].lc); tr[x].rc=merge(tr[x].rc,tr[y].rc); return x; } int gofind(int now,int l,int r,int p) { if(l==r)return tr[now].c; int mid=(l+r)/2; if(p<=mid)return gofind(tr[now].lc,l,mid,p); else return gofind(tr[now].rc,mid+1,r,p); } int findfa(int t,int x) { int F=gofind(rt[t],1,n,x); if(F==x)return x; int tf=findfa(t,F); if(tf!=F) { int root=rt[t]; rt[t]=maketree(0,1,n,x,tf); rt[t]=merge(rt[t],root); } return tf; } int main() { freopen("disjoint.in","r",stdin); freopen("disjoint.out","w",stdout); int Q; scanf("%d%d",&n,&Q); trlen=0;memset(rt,0,sizeof(rt)); for(int i=1;i<=n;i++) { rt[i]=maketree(rt[i],1,n,i,i); rt[i]=merge(rt[i],rt[i-1]); } int op,x,y,tim=0,ans=0; while(Q--) { scanf("%d",&op); if(op==1) { scanf("%d%d",&x,&y); int fx=findfa(tim+n,x); int fy=findfa(tim+n,y); tim++; rt[tim+n]=maketree(rt[tim+n],1,n,fy,fx); rt[tim+n]=merge(rt[tim+n],rt[tim+n-1]); } else if(op==2) { scanf("%d",&x); tim++; rt[tim+n]=rt[x+n]; } else { scanf("%d%d",&x,&y); int fx=findfa(tim+n,x); int fy=findfa(tim+n,y); ans=(fx==fy); printf("%d\n",ans); tim++; rt[tim+n]=rt[tim+n-1]; } } return 0; }
pain and happy in the cruel world.