P3402 可持久化並查集
阿新 • • 發佈:2020-07-10
繼續打打板子熱熱手。
#include<iostream> #include<cstring> #include<algorithm> #include<cmath> #include<cstdlib> #include<climits> #include<stack> #include<vector> #include<queue> #include<set> #include<bitset> #include<map> //#include<regex> #include<cstdio> #include <iomanip> #pragma GCC optimize(2) #define up(i,a,b) for(int i=a;i<b;i++) #define dw(i,a,b) for(int i=a;i>b;i--) #define upd(i,a,b) for(int i=a;i<=b;i++) #define dwd(i,a,b) for(int i=a;i>=b;i--) //#define local typedef long long ll; typedef unsigned long long ull; const double esp = 1e-6; const double pi = acos(-1.0); const int INF = 0x3f3f3f3f; const int inf = 1e9; using namespace std; ll read() { char ch = getchar(); ll x = 0, f = 1; while (ch<'0' || ch>'9') { if (ch == '-')f = -1; ch = getchar(); } while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); } return x * f; } typedef pair<int, int> pir; #define lson l,mid,root<<1 #define rson mid+1,r,root<<1|1 #define lrt root<<1 #define rrt root<<1|1 const int N = 2e5 + 10; int n, m; struct bcj { int par[N * 30]; int height[N * 30]; int tot = 0; int root[N]; int ls[N * 30], rs[N * 30]; void build(int &o,int l,int r) { o = ++tot; int mid = (l + r) >> 1; if (l == r) { par[o] = l; return; } build(ls[o], l, mid); build(rs[o], mid + 1, r); } void merge(int &o, int pre, int l, int r, int pos, int val) { o = ++tot; ls[o] = ls[pre]; rs[o] = rs[pre]; if (l == r) { height[o] = height[pre]; par[o] = val; return; } int mid = (l + r) >> 1; if (pos <= mid)merge(ls[o], ls[pre], l, mid, pos, val); else merge(rs[o], rs[pre], mid + 1, r, pos, val); } void update(int o, int l, int r, int pos) { if (l == r) { height[o]++; return; } int mid = (l + r) >> 1; if (pos <= mid)update(ls[o], l, mid, pos); else update(rs[o], mid + 1, r, pos); } int query(int o, int l, int r, int pos) { if (l == r)return o; int mid = (l + r) >> 1; if (pos <= mid)return query(ls[o], l, mid, pos); else return query(rs[o], mid + 1, r, pos); } int find(int o,int pos) { int now = query(o, 1, n, pos); if (par[now] != pos)return find(o, par[now]); else return now; } }T; int main() { n = read(), m = read(); T.build(T.root[0], 1, n); int a, b, op; int cnt = 0; while (m--) { op = read(); cnt++; if (op==1) { T.root[cnt] = T.root[cnt - 1]; a = read(), b = read(); int pos1 = T.find(T.root[cnt], a); int pos2 = T.find(T.root[cnt], b); if (T.par[pos1] == T.par[pos2])continue; if (T.height[pos1] < T.height[pos2]) swap(pos1, pos2); T.merge(T.root[cnt], T.root[cnt - 1], 1, n, T.par[pos2], T.par[pos1]); if (T.height[pos1] == T.height[pos2]) { T.update(T.root[cnt], 1, n, T.par[pos1]); } } else if (op == 2) { a = read(); T.root[cnt] = T.root[a]; } else { a = read(), b = read(); T.root[cnt] = T.root[cnt - 1]; int pos1 = T.find(T.root[cnt], a); int pos2 = T.find(T.root[cnt], b); if (T.par[pos1] == T.par[pos2]) { printf("1\n"); } else printf("0\n"); } } }