zoukankan      html  css  js  c++  java
  • bzoj3674: 可持久化并查集加强版

    主席树。

    我分不清主席树和可持久化线段树。。

    用主席树记录历史版本。

    然后每个节点保存一个深度,代表以自己为根的树的深度。

    合并时将深度小的树合进深度大的树。

    3673也是一样的,不过那道题不强制在线。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int maxn = 200000 + 10;
    const int maxm = 5000000 + 10;
    
    int n,m,vid;
    int root[maxn],lc[maxm],rc[maxm],v[maxm],dep[maxm]; 
    
    void build(int &x,int l,int r) {
        if(!x) x=++vid;
        if(l==r) {v[x]=l;return;}
        int mid=(l+r)>>1;
        build(lc[x],l,mid);
        build(rc[x],mid+1,r);
    }
    
    void modify(int &x,int y,int l,int r,int pos,int val) {
        x=++vid;
        if(l==r) {v[x]=val; dep[x]=dep[y]; return;}
        lc[x]=lc[y]; rc[x]=rc[y];
        int mid=(l+r)>>1;
        if(pos<=mid) modify(lc[x],lc[y],l,mid,pos,val);
        else modify(rc[x],rc[y],mid+1,r,pos,val);
    }
    
    int query(int x,int l,int r,int pos) {
        if(l==r) return x;
        int mid=(l+r)>>1;
        if(pos<=mid) return query(lc[x],l,mid,pos);
        else return query(rc[x],mid+1,r,pos);    
    }
    
    void add(int x,int l,int r,int pos) {
        if(l==r) {dep[x]++; return;}
        int mid=(l+r)>>1;
        if(pos<=mid) add(lc[x],l,mid,pos);
        else return add(rc[x],mid+1,r,pos);    
    }
    
    int find(int x,int k) {
        int p=query(x,1,n,k);
        if(v[p]==k) return p;
        else return find(x,v[p]);
    }
    
    int op,a,b;
    
    int main() {
        scanf("%d%d",&n,&m);
        build(root[0],1,n);    
        for(int i=1;i<=m;i++) {
            scanf("%d",&op);
            if(op==1) {
                root[i]=root[i-1];
                scanf("%d%d",&a,&b);
                int p=find(root[i],a),q=find(root[i],b);
                if(v[p]==v[q]) continue;
                if(dep[p]>dep[q]) swap(p,q);
                modify(root[i],root[i-1],1,n,v[p],v[q]);
                if(dep[p]==dep[q]) add(root[i],1,n,v[q]);
            }
            else if(op==2) {
                scanf("%d",&a);
                root[i]=root[a];
            }
            else {
                root[i]=root[i-1];
                scanf("%d%d",&a,&b);
                int p=find(root[i],a),q=find(root[i],b);
                printf("%d
    ",v[p]==v[q]?1:0);
            }
        }
        return 0;
    }
  • 相关阅读:
    运维IT必备程序安装包
    网络基础TCP三次握手四次挥手
    新建Weblogic域启动报BEA090403和BEA000386提示密码认证有问题
    Weblogic开发模式和生产产品模式互换
    web api 返回 去除双引号转义符
    freeswitch esl :Rejected by acl “loopback.auto“问题
    freeswitch SIP 服务器一些常用配置
    因果推断综述
    Django 项目配置拆分独立
    wayne编译支持k8s1.16+
  • 原文地址:https://www.cnblogs.com/invoid/p/5663892.html
Copyright © 2011-2022 走看看