n個集合 m個操作
操作:1 a b 合併a,b所在集合
2 k 回到第k次操作之後的狀態(查詢算作操作)
3 a b 詢問a,b是否屬於同一集合,是則輸出1否則輸出0
0水題。把fa陣列可持久化就好了。
#include#include#includeusing namespace std;
inline int read()
while (ch <= '9' && ch >= '0')
return x * flag;
}#define rep(ii, aa, bb) for (int ii = aa; ii <= bb; ii++)
#define n 1000001
#define getmid int mid = l + r >> 1
int n, m;
int root[n], ls[n], rs[n], v[n], sz; // the tree
void build(int &k, int l, int r)
getmid;
build(ls[k], l, mid);
build(rs[k], mid + 1, r);
}int query(int k, int l, int r, int pos)
int getfa(int k, int x)
void update(int l, int r, int x, int &y, int pos, int val)
ls[y] = ls[x];
rs[y] = rs[x];
getmid;
if (pos <= mid) update(l, mid, ls[x], ls[y], pos, val);
else update(mid + 1, r, rs[x], rs[y], pos, val);
}int main()
else if (op == 2) root[i] = root[a];
else
} return 0;
}
bzoj3673 可持久化並查集
bzoj 我們考慮把每個操作建成乙個點 i 對於 1 和 3 操作,連邊 i 1,i 對於 2 操作,連邊 k i,i 容易發現這是一棵樹,並且並查集的操作可以回退,那麼我們直接在樹上dfs,在進入節點 回溯時處理merge split 查詢即可.時間複雜度 o m log n 超短.pragma ...
BZOJ3673 可持久並查集
可以用線段樹維護 每個葉子結點存它父親的位置 查乙個點的父親和正常並查集差不多 記錄每個點的深度 當要相連的兩個點深度相同時 p,q 把q的deep 整體用主席樹維護 copy hzwer的 orz include include using namespace std inline int rea...
BZOJ 3673 可持久化並查集 by zky
n個集合 m個操作 操作 1 a b 合併a,b所在集合 2 k 回到第k次操作之後的狀態 查詢算作操作 3 a b 詢問a,b是否屬於同一集合,是則輸出1否則輸出0 05 6 1 1 2 3 1 2 2 0 3 1 2 2 1 3 1 2 1 0 1可持久化並查集不好寫,我們考慮到並查集的寫法就是...