zoukankan      html  css  js  c++  java
  • P3402 【模板】可持久化并查集 主席树

      

    题目描述

    n个集合 m个操作

    操作:

    • 1 a b 合并a,b所在集合

    • 2 k 回到第k次操作之后的状态(查询算作操作)

    • 3 a b 询问a,b是否属于同一集合,是则输出1否则输出0

    输入格式

    输出格式

    输入输出样例

    输入 #1
    5 6
    1 1 2
    3 1 2
    2 0
    3 1 2
    2 1
    3 1 2
    输出 #1
    1
    0
    1



    主席树维护即可 注意启发式合并
    #include<bits/stdc++.h>
    using namespace std;
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);--i)
    #define ll long long
    #define see(x) (cerr<<(#x)<<'='<<(x)<<endl)
    #define pb push_back
    #define inf 0x3f3f3f3f
    #define CLR(A,v)  memset(A,v,sizeof A)
    typedef pair<int,int>pii;
    //////////////////////////////////
    const int N=2e6+10;
    
    int T[N],t[N<<5],lson[N<<5],rson[N<<5],dep[N<<5],n,m,op,a,b,c,ncnt;
    
    void build(int l,int r,int &pos)
    {
        pos=++ncnt;
        if(l==r){t[pos]=l;return ;}
        int m=(l+r)>>1;
        build(l,m,lson[pos]);
        build(m+1,r,rson[pos]);
    }
    void upnode(int x,int fa,int l,int r,int pre,int &pos)
    {
        pos=++ncnt;t[pos]=t[pre];lson[pos]=lson[pre];rson[pos]=rson[pre];
        if(l==r){t[pos]=fa;dep[pos]=dep[pre];return ;}
        int m=(l+r)>>1;
        if(x<=m)upnode(x,fa,l,m,lson[pos],lson[pos]);
        else upnode(x,fa,m+1,r,rson[pos],rson[pos]);
    }
    int qsum(int x,int l,int r,int pos)
    {
        if(l==r)return pos;
        int m=(l+r)>>1;
        if(x<=m)return qsum(x,l,m,lson[pos]);
        else return qsum(x,m+1,r,rson[pos]);
    }
    void adddep(int x,int l,int r,int pos)
    {
        if(l==r){dep[pos]++;return ;}
        int m=(l+r)>>1;
        if(x<=m)adddep(x,l,m,lson[pos]);
        else adddep(x,m+1,r,rson[pos]);
    }
    int find1(int x,int tt)
    {
        int pos=qsum(x,1,n,tt);
        if(t[pos]==x)return pos;
        return find1(t[pos],tt);
    }
    int main()
    {
        cin>>n>>m;
        build(1,n,T[0]);
        rep(i,1,m)
        {
            cin>>op;
            if(op==1)
            {
                cin>>a>>b;
                T[i]=T[i-1];
                int x=find1(a,T[i]),y=find1(b,T[i]);
                if(t[x]==t[y])continue;
                if(dep[x]>dep[y])swap(x,y);
                upnode(t[x],t[y],1,n,T[i-1],T[i]);
                if(dep[x]==dep[y])adddep(y,1,n,T[i]);
            }
            else if(op==2)
            {
                int k;cin>>k;
                T[i]=T[k];
            }
            else
            {
                T[i]=T[i-1];
                cin>>a>>b;
                if( t[find1(a,T[i])]==t[find1(b,T[i])] )
                    printf("1
    ");
                else printf("0
    ");
            }
        }
        return 0;
    }
    View Code



  • 相关阅读:
    CF1312G Autocompletion
    UOJ#11. 【UTR #1】ydc的大树
    CF51F Caterpillar
    CF295D Greg and Caves
    CF288E Polo the Penguin and Lucky Numbers
    CF401D Roman and Numbers
    CF543D Road Improvement
    CF938F Erasing Substrings
    [AGC024E] Sequence Growing Hard
    CF261D Maxim and Increasing Subsequence
  • 原文地址:https://www.cnblogs.com/bxd123/p/11344357.html
Copyright © 2011-2022 走看看