题目大意:维护一种数据结构实现可持久化并查集。
思路:利用可持久化线段树实现可持久化数组维护可持久化并查集。(不知道3674哪里加强了。。。
CODE:
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define RANGE 8000010 #define MAX 200200 using namespace std; struct SegTree{ SegTree *son[2]; int val; void *operator new(size_t,SegTree *_,SegTree *__,int ___); }mempool[RANGE],*C = mempool,*father[MAX],*h[MAX]; void *SegTree:: operator new(size_t,SegTree *_,SegTree *__,int ___) { C->son[0] = _; C->son[1] = __; C->val = ___; return C++; } int cnt,asks; int verson[MAX],now_ver,latest; int last_ans; SegTree *Modify(SegTree *a,int l,int r,int x,int val) { if(l == r) return new(NULL,NULL,val)SegTree; int mid = (l + r) >> 1; if(x <= mid) return new(Modify(a->son[0],l,mid,x,val),a->son[1],0)SegTree; return new(a->son[0],Modify(a->son[1],mid + 1,r,x,val),0)SegTree; } int Ask(SegTree *a,int l,int r,int x) { if(l == r) return a->val; int mid = (l + r) >> 1; if(x <= mid) return Ask(a->son[0],l,mid,x); return Ask(a->son[1],mid + 1,r,x); } inline int Find(int x) { int y; while(x) x = Ask(father[now_ver],1,cnt,y = x); return y; } inline void Unite(int x,int y) { int fx = Find(x),fy = Find(y); if(fx == fy) return ; ++latest; int hx = Ask(h[now_ver],1,cnt,fx); int hy = Ask(h[now_ver],1,cnt,fy); if(hx < hy) swap(x,y),swap(fx,fy),swap(hx,hy); father[latest] = Modify(father[now_ver],1,cnt,fy,fx); h[latest] = Modify(h[now_ver],1,cnt,fx,hx + hy); now_ver = latest; } inline bool Query(int x,int y) { return Find(x) == Find(y); } int main() { cin >> cnt >> asks; father[0] = new(C,C,0)SegTree; h[0] = new(C,C,1)SegTree; for(int flag,x,y,i = 1; i <= asks; ++i) { scanf("%d",&flag); if(flag == 1) { scanf("%d%d",&x,&y); x ^= last_ans,y ^= last_ans; Unite(x,y); } else if(flag == 2) { scanf("%d",&x); x ^= last_ans; now_ver = verson[x]; } else { scanf("%d%d",&x,&y); x ^= last_ans,y ^= last_ans; printf("%d\n",last_ans = Query(x,y)); } verson[i] = now_ver; } return 0; }