zoukankan      html  css  js  c++  java
  • bzoj3673可持久化并查集

    n个集合 m个操作
    操作:
    1 a b 合并a,b所在集合
    2 k 回到第k次操作之后的状态(查询算作操作)
    3 a b 询问a,b是否属于同一集合,是则输出1否则输出0

    0<n,m<=2*10^4

    可持久化并查集是用可持久化线段树维护的,唯一的区别就在于多了一个find操作,可持久化线段树实际上只维护了一个可持久化数组,只需要维护最下面的一层即可

    /**************************************************************
        Problem: 3673
        User: walfy
        Language: C++
        Result: Accepted
        Time:120 ms
        Memory:13096 kb
    ****************************************************************/
     
    //#pragma comment(linker, "/stack:200000000")
    //#pragma GCC optimize("Ofast,no-stack-protector")
    //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
    //#pragma GCC optimize("unroll-loops")
    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define pi acos(-1.0)
    #define ll long long
    #define mod 1000000007
    #define C 0.5772156649
    //#define ls l,m,rt<<1
    //#define rs m+1,r,rt<<1|1
    #define pil pair<int,ll>
    #define pii pair<int,int>
    #define cd complex<double>
    #define ull unsigned long long
    #define base 1000000000000000000
    #define fio ios::sync_with_stdio(false);cin.tie(0)
     
    using namespace std;
     
    const double g=10.0,eps=1e-12;
    const int N=20000+10,maxn=1200000+10,inf=0x3f3f3f3f,INF=0x3f3f3f3f3f3f3f3f;
     
    int ls[N*50],rs[N*50],rt[N],tot,val[N*50];
    int n,m;
    void build(int &o,int l,int r)
    {
        o=++tot;
        if(l==r)
        {
            val[o]=l;
            return ;
        }
        int m=(l+r)>>1;
        build(ls[o],l,m);build(rs[o],m+1,r);
    }
    void update(int &o,int l,int r,int last,int pos,int x)
    {
        o=++tot;
        ls[o]=ls[last];rs[o]=rs[last];
        if(l==r)
        {
            val[o]=x;
            return ;
        }
        int m=(l+r)>>1;
        if(pos<=m)update(ls[o],l,m,ls[last],pos,x);
        else update(rs[o],m+1,r,rs[last],pos,x);
    }
    int query(int o,int l,int r,int pos)
    {
        if(l==r)return val[o];
        int m=(l+r)>>1;
        if(pos<=m)return query(ls[o],l,m,pos);
        else return query(rs[o],m+1,r,pos);
    }
    int Find(int &o,int x)
    {
        int te=query(o,1,n,x);
        if(te==x)return x;
        else
        {
            int pp=Find(o,te);
            update(o,1,n,o,te,pp);
            return pp;
        }
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        build(rt[0],1,n);
        for(int i=1;i<=m;i++)
        {
            int op;
            scanf("%d",&op);
            if(op==1)
            {
                int x,y;
                scanf("%d%d",&x,&y);
                int fx=Find(rt[i-1],x),fy=Find(rt[i-1],y);
                if(fx==fy)rt[i]=rt[i-1];
                else update(rt[i],1,n,rt[i-1],fx,fy);
            }
            else if(op==2)
            {
                int x;scanf("%d",&x);
                rt[i]=rt[x];
            }
            else
            {
                int x,y;scanf("%d%d",&x,&y);
                int fx=Find(rt[i-1],x),fy=Find(rt[i-1],y);
                if(fx==fy)puts("1");
                else puts("0");
                rt[i]=rt[i-1];
            }
        }
        return 0;
    }
    /********************
     
    ********************/
    View Code
  • 相关阅读:
    NAS与SAN RAID
    使用slice和concat对数组的深拷贝和浅拷贝
    使用JSON.parse(),JSON.stringify()实现对对象的深拷贝
    ng2父子模块通信@ViewChild和@Inject
    js避免命名冲突
    JSON.parse()和JSON.stringify()
    object类型转换为Array类型
    Angular 2 ViewChild & ViewChildren
    ElementRef, @ViewChild & Renderer
    ng2父子模块数据交互
  • 原文地址:https://www.cnblogs.com/acjiumeng/p/8806514.html
Copyright © 2011-2022 走看看