• BZOJ 3674 可持久化并查集


    https://www.lydsy.com/JudgeOnline/problem.php?id=3674

    用可持久化数组维护并查集的fa数组,

    查询时间复杂度为nlognlogn,一个log是并查集的时间复杂度,采用按秩合并的操作,需要注意的是按秩合并的秩意思为当前最大结点下的树的最大深度。

    另一个log是主席树查询的时间复杂度

    #include <map>
    #include <set>
    #include <ctime>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <string>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <sstream>
    #include <iostream>
    #include <algorithm>
    #include <functional>
    using namespace std;
    #define For(i, x, y) for(int i=x;i<=y;i++)  
    #define _For(i, x, y) for(int i=x;i>=y;i--)
    #define Mem(f, x) memset(f,x,sizeof(f))  
    #define Sca(x) scanf("%d", &x)
    #define Sca2(x,y) scanf("%d%d",&x,&y)
    #define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
    #define Scl(x) scanf("%lld",&x);  
    #define Pri(x) printf("%d
    ", x)
    #define Prl(x) printf("%lld
    ",x);  
    #define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
    #define LL long long
    #define ULL unsigned long long  
    #define mp make_pair
    #define PII pair<int,int>
    #define PIL pair<int,long long>
    #define PLL pair<long long,long long>
    #define pb push_back
    #define fi first
    #define se second 
    typedef vector<int> VI;
    int read(){int x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();}
    while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;}
    const double eps = 1e-9;
    const int maxn = 2e5 + 10;
    const int INF = 0x3f3f3f3f;
    const int mod = 1e9 + 7; 
    int N,M,K;
    int T[maxn],tot;
    struct Tree{
        int lt,rt;
        int fa,size;
    }tree[maxn * 52];
    int fa[maxn],Size[maxn];
    void newnode(int &t){
        t = ++tot;
        tree[t].lt = tree[t].rt = tree[t].fa = 0;
    }
    void Build(int &t,int l,int r){
        newnode(t);
        if(l == r){
            tree[t].fa = l;
            tree[t].size = 0;
            return;
        }
        int m = l + r >> 1;
        Build(tree[t].lt,l,m); Build(tree[t].rt,m + 1,r);
    }
    int query(int t,int l,int r,int x){
        if(l == r){
            Size[x] = tree[t].size;
            return tree[t].fa;
        }
        int m = l + r >> 1;
        if(x <= m) return query(tree[t].lt,l,m,x);
        else return query(tree[t].rt,m + 1,r,x);
    }
    void update(int &t,int pre,int l,int r,int x){
        newnode(t);
        tree[t] = tree[pre];
        if(l == r){
            tree[t].fa = fa[x];
            tree[t].size = Size[x];
            return;
        }
        int m = l + r >> 1;
        if(x <= m) update(tree[t].lt,tree[pre].lt,l,m,x);
        else update(tree[t].rt,tree[pre].rt,m + 1,r,x);
    }
    int find(int id,int x){
        int f = query(T[id],1,N,x);
        if(f == x) return x;
        return find(id,f);
    }
    int main(){
        //freopen("C.in","r",stdin);
        Sca2(N,M);    
        Build(T[0],1,N);
        int ans = 0; 
        for(int i = 1; i <= M; i ++){
            int op = read();
            if(op == 1){
                int a = read() ^ ans,b = read() ^ ans;
                a = find(i - 1,a); b = find(i - 1,b);
                if(Size[a] > Size[b]) swap(a,b);
                fa[a] = b;
                update(T[i],T[i - 1],1,N,a);
                if(Size[a] == Size[b]){
                    Size[b]++; fa[b] = b;
                    int x;
                    update(x,T[i],1,N,b);
                    T[i] = x;
                } 
            }else if(op == 2){
                int k = read() ^ ans;
                T[i] = T[k];
            }else if(op == 3){
                T[i] = T[i - 1];
                int a = read() ^ ans,b = read() ^ ans;
                a = find(i,a); b = find(i,b);
                ans = (a == b);
                if(a == b) puts("1");
                else puts("0");
            }    
            
        }
        return 0;
    }
  • 相关阅读:
    Android菜鸟的成长笔记(5)——Android系统源代码你下载了吗?
    2014年你不用担心的10件事
    Android菜鸟的成长笔记(4)——你真的理解了吗?
    3. MariaDB设置主从复制
    2. MariaDB激活二进制日志
    如何在CSDN博客自定义栏目中添加“给我写信”
    告别码农,成为真正的程序员
    微信公众平台开发(75)自定义菜单
    大文件分片上传,断点续传,秒传 实现
    大文件上传-大视频上传,T级别的,求解决方案
  • 原文地址:https://www.cnblogs.com/Hugh-Locke/p/10595602.html
Copyright © 2020-2023  润新知