(前言:我想我需要有人给我讲一遍!!!!!!)
亲爱的qtf感冒了.....我可真是中国好室友qwqqqq
好吧我是不会说打着给她喂药的名号回屋玩手机QAQ
今天算是很不容易的看懂了可持续化并查集...(但还不算很懂
3402 【模板】可持久化并查集
n个集合 m个操作
操作:
-
1 a b
合并a,b所在集合 -
2 k
回到第k次操作之后的状态(查询算作操作) -
3 a b
询问a,b是否属于同一集合,是则输出1否则输出0
解答写在了代码里qwqqqq
#include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #define max 2000005 using namespace std; int k,l,r,ls[max],rs[max],pos,res,sz,v[max],root[max],i; int n,m;//我也不知道v数组是干什么的... int c;//大概就是存个数? int a,b;//rs和ls就是用来存左右子树的吧QAQ int deep[max]; int read()//快读qwq { int ans = 0; int op = 1; int ch = getchar(); while(ch < '0'||ch > '9') { if(ch == '-')op = -1; ch = getchar(); } while(ch >= '0' && ch <= '9') { ans *= 10; ans += ch - '0'; ch = getchar(); } return ans*op; } void build(int &k,int l,int r)//建树 { if(k==0)k = ++sz;//向下传递? if(l == r) { v[k] = l;//如果是子节点 return ; } int mid = (l+r) / 2; build(ls[k],l,mid); build(rs[k],mid+1,r); } void add(int k,int l,int r,int pos)//添加 { if(l == r) { deep[k]++;//加深 return ; } int mid = (l+r) / 2; if(pos <= mid) { add(ls[k],l,mid,pos); } else add(rs[k],mid + 1,r,pos); } int query(int k,int l,int r,int res)//查询 { if(l == r)return k;//到达子节点 也就是无法继续查询 int mid = (l + r) / 2; if(res <= mid)return query(ls[k],l,mid,res); else return query(rs[k],mid + 1,r,res); } void modify(int l,int r,int x,int &y,int pos,int val)//修改 x,y是要修改的数? { y = ++sz; if(l == r) { v[y] = val;//val可不是价值的意思 deep[y] = deep[x]; return ; } ls[y] = ls[x]; rs[y] = rs[x]; int mid = (l + r) / 2; if(pos <= mid) { modify(l,mid,ls[x],ls[y],pos,val); } else modify(mid + 1,r,rs[x],rs[y],pos,val); } int find(int k,int x) { int p = query(k,1,n,x);//在1-n的范围里 找以k为节点的x? if(x == v[p]) { return p; } return find (k,v[p]);//我我我已经解释不了了.... } int main(){//下面就很好理解啦 n = read();//我就不说啦 m = read(); build(root[0],1,n); for(int i = 1;i <= m;++ i) { c = read(); if(c == 1) { a = read(); b = read(); root[i] = root[i-1]; int p = find(root[i],a); int q = find(root[i],b); if(v[p] == v[q])continue; if(deep[p] > deep[q]) { swap(p,q); } modify(1,n,root[i-1],root[i],v[p],v[q]); if(deep[q] == deep[p]) add(root[i],1,n,v[q]); } if(c == 2) { k = read(); root[i] = root[k]; } if(c == 3) { root[i] = root[i-1]; a = read(); b = read(); int p = find(root[i],a); int q = find(root[i],b); if(v[p] == v[q]) { printf("1\n"); } else printf("0\n"); } } return 0; }
要是有人会的话....
能给我讲一下嘛
(好吧 我应该在做白日梦QAQ