BZOJ3674可持久化并查集(模板)

没什么可说的,就是一个可持久化线段树维护一个数组fa以及deep按秩合并好了

注意一下强制在线

蒟蒻的我搞了好长时间QAQ

贴代码:

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 struct trnt{
  5     int ls;
  6     int rs;
  7     int fa;
  8     int dp;
  9 }tr[10000005];
 10 int root[300000];
 11 int siz;
 12 int n,m;
 13 int lastans;
 14 void Tr_build(int l,int r,int &spc)
 15 {
 16     if(!spc)
 17         spc=++siz;
 18     if(l==r)
 19     {
 20         tr[spc].fa=l;
 21         return ;
 22     }
 23     int mid=(l+r)/2;
 24     Tr_build(l,mid,tr[spc].ls);
 25     Tr_build(mid+1,r,tr[spc].rs);
 26     return ; 
 27 }
 28 int ask(int l,int r,int pos,int spc)
 29 {
 30     if(l==r)
 31         return spc;
 32     int mid=(l+r)/2;
 33     if(pos<=mid)
 34         return ask(l,mid,pos,tr[spc].ls);
 35     return ask(mid+1,r,pos,tr[spc].rs);
 36 }
 37 int finf(int rt,int x)
 38 {
 39     int ff=ask(1,n,x,rt);
 40     if(tr[ff].fa==x)
 41         return ff;
 42     return finf(rt,tr[ff].fa);
 43 }
 44 void unin(int l,int r,int &spc,int last,int pos,int ff)
 45 {
 46     spc=++siz;
 47     if(l==r)
 48     {
 49         tr[spc].fa=ff;
 50         tr[spc].dp=tr[last].dp;
 51         return ;
 52     }
 53     tr[spc].ls=tr[last].ls;
 54     tr[spc].rs=tr[last].rs;
 55     int mid=(l+r)/2;
 56     if(pos<=mid)
 57         unin(l,mid,tr[spc].ls,tr[last].ls,pos,ff);
 58     else
 59         unin(mid+1,r,tr[spc].rs,tr[last].rs,pos,ff);
 60     return ;
 61 }
 62 void grow(int l,int r,int pos,int spc)
 63 {
 64     if(l==r)
 65     {
 66         tr[spc].dp++;
 67         return ;
 68     }
 69     int mid=(l+r)/2;
 70     if(pos<=mid)
 71         grow(l,mid,pos,tr[spc].ls);
 72     else
 73         grow(mid+1,r,pos,tr[spc].rs);
 74     return ; 
 75 }
 76 int main()
 77 {
 78     scanf("%d%d",&n,&m);
 79     Tr_build(1,n,root[0]);
 80     for(int i=1;i<=m;i++)
 81     {
 82         root[i]=root[i-1];
 83         int cmd;
 84         scanf("%d",&cmd);
 85         if(cmd==1)
 86         {
 87             int x,y;
 88             scanf("%d%d",&x,&y);
 89             x=x^lastans;
 90             y=y^lastans;
 91             x=finf(root[i],x);
 92             y=finf(root[i],y);
 93             if(tr[x].fa==tr[y].fa)
 94                 continue;
 95             if(tr[x].dp>tr[y].dp)
 96                 std::swap(x,y);
 97             unin(1,n,root[i],root[i-1],tr[x].fa,tr[y].fa);
 98             if(tr[x].dp==tr[y].dp)
 99                 grow(1,n,tr[y].fa,root[i]);
100         }else if(cmd==2)
101         {
102             int x;
103             scanf("%d",&x);
104             x=x^lastans;
105             root[i]=root[x];
106         }else{
107             int x,y;
108             scanf("%d%d",&x,&y);
109             x=x^lastans;
110             y=y^lastans;
111             x=finf(root[i],x);
112             y=finf(root[i],y);
113             if(tr[x].fa==tr[y].fa)
114                 lastans=1;
115             else
116                 lastans=0;
117             printf("%d\n",lastans);
118         }
119     }
120     return 0;
121 }

 

posted @ 2018-08-25 21:18  Unstoppable728  阅读(161)  评论(0编辑  收藏  举报