Luogu3402【模板】可持久化并查集 (主席树)

匿名 (未验证) 提交于 2019-12-02 23:49:02

\(depth\)按秩合并,不能直接启发,数组开40倍左右

#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #define R(a,b,c) for(register int  a = (b); a <= (c); ++ a) #define nR(a,b,c) for(register int  a = (b); a >= (c); -- a) #define Max(a,b) ((a) > (b) ? (a) : (b)) #define Min(a,b) ((a) < (b) ? (a) : (b)) #define Fill(a,b) memset(a, b, sizeof(a)) #define Abs(a) ((a) < 0 ? -(a) : (a)) #define Swap(a,b) a^=b^=a^=b #define ll long long  //#define ON_DEBUG  #ifdef ON_DEBUG  #define D_e_Line printf("\n\n----------\n\n") #define D_e(x)  cout << #x << " = " << x << endl #define Pause() system("pause") #define FileOpen() freopen("in.txt","r",stdin);  #else  #define D_e_Line ; #define D_e(x)  ; #define Pause() ; #define FileOpen() ;  #endif  struct ios{     template<typename ATP>ios& operator >> (ATP &x){         x = 0; int f = 1; char c;         for(c = getchar(); c < '0' || c > '9'; c = getchar()) if(c == '-')  f = -1;         while(c >= '0' && c <= '9') x = x * 10 + (c ^ '0'), c = getchar();         x*= f;         return *this;     } }io; using namespace std;  const int N = 200005;  int n;  int T[N], L[N * 40], R[N * 40]; int fa[N * 40], dep[N * 40]; int treeIndex;   #define lson L[rt], l, mid #define rson R[rt], mid + 1, r inline void Build(int &rt, int l, int r){     rt = ++treeIndex;     if(l == r){         fa[rt] = l;         return;     }     int mid = (l + r) >> 1;     Build(lson), Build(rson); } inline void Updata(int &rt, int pre, int l, int r, int x, int father){     rt = ++treeIndex;     if(l == r){         fa[rt] = father;         dep[rt] = dep[pre]; // inherit the last depth to union by rank         return;     }     L[rt] = L[pre], R[rt] = R[pre]; // don't forget initial this     int mid = (l + r) >> 1;     if(x <= mid)         Updata(L[rt], L[pre], l, mid, x, father);     else         Updata(R[rt], R[pre], mid + 1, r, x, father); } inline int Query(int rt, int l, int r, int x){     if(l == r) return rt;     int mid = (l + r) >> 1;     if(x <= mid)         return Query(lson, x);     else         return Query(rson, x); } inline void AddDepth(int rt, int l, int r, int x){     if(l == r){         ++dep[rt]; return;     }     int mid = (l + r) >> 1;     if(x <= mid)         AddDepth(lson, x);     else         AddDepth(rson, x); } inline int Find(int rt, int x){     int fx = Query(rt, 1, n, x);     return x == fa[fx] ? fx : Find(rt, fa[fx]); }  int main() {     FileOpen();     int m;     io >> n >> m;          Build(T[0],1,n);          R(i,1,m){         int opt;         io >> opt;         switch(opt){             case 1:{                 T[i] = T[i - 1]; // inherit the last edition                                  int x, y;                 io >> x >> y;                 int fx = Find(T[i], x), fy = Find(T[i], y);                 if(fa[fx] == fa[fy]) continue;                  if(dep[fx] > dep[fy]) Swap(fx, fy); // lighter lord heavier                 Updata(T[i], T[i - 1], 1, n, fa[fx], fa[fy]);                 if(dep[fx] == dep[fy]) AddDepth(T[i], 1, n, fa[fy]);                 break;             }             case 2:{                 int x;                 io >> x;                 T[i] = T[x];                 break;             }             case 3:{                 T[i] = T[i - 1]; // inherit the last edition                                  int x, y;                 io >> x >> y;                 int fx = Find(T[i], x), fy = Find(T[i], y);                  if(fa[fx] == fa[fy])                     printf("1\n");                 else                     printf("0\n");                 break;             }         }     }          return 0; }
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!