BZOJ 3674 可持久化并查集加强版(按秩合并版本)
1 /* 2 bzoj 3674: 可持久化并查集加强版 3 http://www.lydsy.com/JudgeOnline/problem.php?id=3674 4 用可持久化线段树维护可持久化数组从而实现可持久化并查集 5 可持久化线段树+并查集+按秩合并+读入优化 6 */ 7 #include <cstdio> 8 #include <algorithm> 9 using namespace std; 10 const int Nmax=200005; 11 int root_fa[Nmax],root_rankk[Nmax]; 12 13 inline int read() 14 { 15 int x=0;char ch=getchar(); 16 while(ch>'9'||ch<'0')ch=getchar(); 17 while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} 18 return x; 19 } 20 struct Node 21 { 22 int ls; 23 int rs; 24 int data; 25 }; 26 Node fa[40*Nmax]; 27 Node rankk[40*Nmax]; 28 int n,m,ans,a,b,k; 29 int size_fa,size_rankk; 30 31 void build_rankk(int &root,int l,int r) 32 { 33 root=size_rankk++; 34 int mid=(l+r)>>1; 35 if(l==r) 36 { 37 rankk[root].data=0; 38 return; 39 } 40 build_rankk(rankk[root].ls,l,mid); 41 build_rankk(rankk[root].rs,mid+1,r); 42 } 43 44 void insert_rankk(int last,int &root,int pos,int l,int r) 45 { 46 rankk[size_rankk]=rankk[last]; 47 root=size_rankk; 48 size_rankk++; 49 if(rankk[root].ls==rankk[root].rs) 50 { 51 rankk[root].data++; 52 return; 53 } 54 int mid=(l+r)>>1; 55 if(pos<=mid) 56 insert_rankk(rankk[last].ls,rankk[root].ls,pos,l,mid); 57 else 58 insert_rankk(rankk[last].rs,rankk[root].rs,pos,mid+1,r); 59 } 60 61 int search_rankk(int root,int pos,int l,int r) 62 { 63 if(rankk[root].ls==rankk[root].rs) 64 return rankk[root].data; 65 int mid=(l+r)>>1; 66 if(pos<=mid) 67 return search_rankk(rankk[root].ls,pos,l,mid); 68 else 69 return search_rankk(rankk[root].rs,pos,mid+1,r); 70 } 71 72 void build_fa(int &root,int l,int r) 73 { 74 root=size_fa++; 75 int mid=(l+r)>>1; 76 if(l==r) 77 { 78 fa[root].data=l; 79 return; 80 } 81 build_fa(fa[root].ls,l,mid); 82 build_fa(fa[root].rs,mid+1,r); 83 } 84 85 void insert_fa(int last,int &root,int pos,int data,int l,int r) 86 { 87 fa[size_fa]=fa[last]; 88 root=size_fa; 89 size_fa++; 90 if(fa[root].ls==fa[root].rs) 91 { 92 // printf("root:%d,l:%d,data:%d\n",root,fa[root].l,data); 93 fa[root].data=data; 94 return; 95 } 96 int mid=(l+r)>>1; 97 if(pos<=mid) 98 insert_fa(fa[last].ls,fa[root].ls,pos,data,l,mid); 99 else 100 insert_fa(fa[last].rs,fa[root].rs,pos,data,mid+1,r); 101 } 102 103 int search_fa(int root,int pos,int l,int r) 104 { 105 if(fa[root].ls==fa[root].rs) 106 return fa[root].data; 107 int mid=(l+r)>>1; 108 if(pos<=mid) 109 return search_fa(fa[root].ls,pos,l,mid); 110 else 111 return search_fa(fa[root].rs,pos,mid+1,r); 112 } 113 114 int find(int root,int x) 115 { 116 // if(x==0) 117 // printf("error!!!!\n"); 118 int fa=search_fa(root,x,1,n); 119 if(fa!=x) 120 return find(root,fa); 121 else 122 return fa; 123 } 124 125 // void watch(int root,int l,int r) 126 // { 127 // printf("tree[%d].l=%d,tree[%d].r=%d,tree[%d].data=%d\n",root,fa[root].l,root,fa[root].r,root,fa[root].data); 128 // if(l==r) 129 // return; 130 // int mid=(l+r)>>1; 131 // watch(fa[root].ls,l,mid); 132 // watch(fa[root].rs,mid+1,r); 133 // } 134 135 int main() 136 { 137 freopen("bzoj3674.in","r",stdin); 138 //scanf("%d%d",&n,&m); 139 n=read(); 140 m=read(); 141 ans=0; 142 int q; 143 build_fa(root_fa[0],1,n); 144 build_rankk(root_rankk[0],1,n); 145 // printf("the 0 watch:\n"); 146 // watch(root_fa[0],1,n); 147 for(int i=1;i<=m;i++) 148 { 149 //scanf("%d",&q); 150 q=read(); 151 if(q==1) 152 { 153 a=read(); 154 b=read(); 155 // scanf("%d%d",&a,&b); 156 a^=ans;b^=ans; 157 int rt1=find(root_fa[i-1],a),rt2=find(root_fa[i-1],b); 158 // printf("root[%d]=%d,root[%d]=%d\n",a,rt1,b,rt2); 159 if(rt1==rt2) 160 { 161 root_fa[i]=root_fa[i-1]; 162 root_rankk[i]=root_rankk[i-1]; 163 } 164 else 165 { 166 int rk1=search_rankk(root_rankk[i-1],rt1,1,n),rk2=search_rankk(root_rankk[i-1],rt2,1,n); 167 if(rk1<rk2) 168 { 169 insert_fa(root_fa[i-1],root_fa[i],rt1,rt2,1,n); 170 root_rankk[i]=root_rankk[i-1]; 171 } 172 else 173 { 174 insert_fa(root_fa[i-1],root_fa[i],rt2,rt1,1,n); 175 if(rk1==rk2) 176 insert_rankk(root_rankk[i-1],root_rankk[i],rt1,1,n); 177 else 178 root_rankk[i]=root_rankk[i-1]; 179 } 180 } 181 // printf("search_fa[2]=%d\n",search_fa(root_fa[1],2) ); 182 // printf("root[%d]=%d,root[%d]=%d\n",a,find(root_fa[i],a),b,find(root_fa[i],b)); 183 } 184 else if(q==2) 185 { 186 k=read(); 187 // scanf("%d",&k); 188 k^=ans; 189 root_fa[i]=root_fa[k]; 190 root_rankk[i]=root_rankk[k]; 191 } 192 else if(q==3) 193 { 194 a=read(); 195 b=read(); 196 // scanf("%d%d",&a,&b); 197 root_fa[i]=root_fa[i-1]; 198 root_rankk[i]=root_rankk[i-1]; 199 a^=ans; 200 b^=ans; 201 if(find(root_fa[i],a)==find(root_fa[i],b)) 202 ans=1; 203 else 204 ans=0; 205 printf("%d\n",ans); 206 } 207 //insert_fa(root_fa[i-1],root_fa[i],2,3); 208 // printf("root_fa[%d]:%d\n",i,root_fa[i]); 209 // printf("the %d watch:\n",i); 210 // watch(root_fa[i],1,n); 211 } 212 return 0; 213 }