• [BZOJ]3674: 可持久化并查集加强版


    题目大意:n个点,三种操作:1.将点a点b连在一起;2.将当前状态退回到第k次操作时的状态;3.询问点a和点b是否连通。(n,操作数量<=200,000)

    思路:可持久化并查集其实就是可持久化数组,我们用线段树代替数组,就只要打个可持久化线段树就可以了。路径压缩复杂度是均摊的不能可持久化,我们按秩合并,维护并查集每块的大小,连边把小的往大连,可以证明连出的最大深度为logn,总复杂度O(nlogn^2)。

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    inline int read()
    {
        int x;char c;
        while((c=getchar())<'0'||c>'9');
        for(x=c-'0';(c=getchar())>='0'&&c<='9';)x=(x<<3)+(x<<1)+c-'0';
        return x;
    }
    #define MN 200000
    #define ND 8000000
    struct data{int f,s;};
    struct node{int l,r;data x;}t[ND+5];
    int n,rt[MN+5],tn,p;
    int build(int l,int r)
    {
        int p=++tn,mid=l+r>>1;
        if(l==r)t[p].x=(data){l,1};
        else t[p].l=build(l,mid),t[p].r=build(mid+1,r);
        return p;
    }
    data query(int k,int x)
    {
        for(int l=1,r=n;;)
        {
            if(l==r)return t[k].x;
            int mid=l+r>>1;
            if(x>mid)k=t[k].r,l=mid+1;
            else k=t[k].l,r=mid;
        }
    }
    int change(int k,int l,int r,int x,data d)
    {
        int p=++tn,mid=l+r>>1;
        if(l==r)t[p].x=d;
        else if(x>mid)t[p].l=t[k].l,t[p].r=change(t[k].r,mid+1,r,x,d);
        else t[p].l=change(t[k].l,l,mid,x,d),t[p].r=t[k].r;
        return p;
    }
    data gf(int k)
    {
        data d=query(rt[p],k);
        return d.f==k?d:gf(d.f);
    }
    int main()
    {
        int m,x,y,l=0;data a,b;
        n=read();m=read();
        rt[0]=build(1,n);
        for(p=1;p<=m;++p)
        {
            rt[p]=rt[p-1];x=read();y=read()^l;
            if(x==1)if((a=gf(y)).f!=(b=gf(read()^l)).f)
            {
                if(a.s>b.s)swap(a,b);
                rt[p]=change(rt[p],1,n,a.f,(data){b.f,a.s});
                rt[p]=change(rt[p],1,n,b.f,(data){b.f,a.s+b.s});
            }
            if(x==2)rt[p]=rt[y];
            if(x==3)printf("%d
    ",l=(gf(y).f==gf(read()).f));
        }
    }
  • 相关阅读:
    IOS开发环境
    IOS开发环境搭建
    Eclipse简明使用教程(java集成开发环境)
    分布式相关
    成为架构师之路认识分布式架构
    什么是分布式系统,如何学习分布式系统
    分布式定义
    VIM命令详解
    vim常用命令
    vi/vim 命令使用详解
  • 原文地址:https://www.cnblogs.com/ditoly/p/BZOJ3674.html
Copyright © 2020-2023  润新知