zoukankan      html  css  js  c++  java
  • bzoj3673可持久化并查集 by zky&&bzoj3674可持久化并查集加强版

    bzoj3673可持久化并查集 by zky

    题意:

    维护可以恢复到第k次操作后的并查集。

    题解:

    用可持久化线段树维护并查集的fa数组和秩(在并查集里的深度),不能路径压缩所以用按秩启发式合并,可以使合并均摊复杂度为O(nlog2n)。可持久化线段树实际上就是在更新节点时按主席树的插入方式新建一条路径(其实主席树就是可持久化权值线段树)。

    代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #define maxn 30000
     5 #define inc(i,j,k) for(int i=j;i<=k;i++)
     6 using namespace std;
     7 
     8 int fa[maxn*15],ch[maxn*15][2],dep[maxn*15],pos[maxn*15],sz,n,m,rt[maxn];
     9 inline int read(){
    10     char ch=getchar(); int f=1,x=0;
    11     while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();} while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    12     return f*x;
    13 }
    14 void build(int &x,int l,int r){
    15     x=++sz; if(l==r){fa[x]=l; dep[x]=1; pos[x]=l; return;}
    16     int mid=(l+r)>>1; build(ch[x][0],l,mid); build(ch[x][1],mid+1,r);
    17 }
    18 void updatefa(int &x,int l,int r,int a,int b){
    19     sz++; fa[sz]=fa[x]; dep[sz]=dep[x]; pos[sz]=pos[x]; ch[sz][0]=ch[x][0]; ch[sz][1]=ch[x][1];
    20     x=sz; if(l==r){fa[x]=b; return;}
    21     int mid=(l+r)>>1; if(a<=mid)updatefa(ch[x][0],l,mid,a,b);else updatefa(ch[x][1],mid+1,r,a,b);
    22 }
    23 void updatedep(int &x,int l,int r,int a,int b){
    24     sz++; fa[sz]=fa[x]; dep[sz]=dep[x]; pos[sz]=pos[x]; ch[sz][0]=ch[x][0]; ch[sz][1]=ch[x][1];
    25     x=sz; if(l==r){dep[x]=b; return;}
    26     int mid=(l+r)>>1; if(a<=mid)updatedep(ch[x][0],l,mid,a,b);else updatedep(ch[x][1],mid+1,r,a,b);
    27 }
    28 int query(int x,int l,int r,int a){
    29     if(l==r)return x; int mid=(l+r)>>1;
    30     if(a<=mid)return query(ch[x][0],l,mid,a);else return query(ch[x][1],mid+1,r,a);
    31 }
    32 int find(int x,int y){
    33     int z=query(x,1,n,y); if(fa[z]==pos[z])return z;else return find(x,fa[z]);
    34 }
    35 void merge(int &s,int x,int y){
    36     int z1=find(s,x),z2=find(s,y); if(pos[z1]==pos[z2])return; if(dep[z1]>dep[z2])swap(z1,z2);
    37     int abc=max(dep[z2],dep[z1]+1); updatefa(s,1,n,pos[z1],pos[z2]); updatedep(s,1,n,pos[z2],abc);
    38 }
    39 int main(){
    40     n=read(); m=read(); build(rt[0],1,n);
    41     inc(i,1,m){
    42         int opt=read();
    43         if(opt==1){int a=read(),b=read(); rt[i]=rt[i-1]; merge(rt[i],a,b);}
    44         if(opt==2){int k=read(); rt[i]=rt[k];}
    45         if(opt==3){
    46             int a=read(),b=read(); rt[i]=rt[i-1];
    47             if(pos[find(rt[i],a)]==pos[find(rt[i],b)])puts("1");else puts("0");
    48         }
    49     }
    50     return 0;
    51 }

    ------------------------------------------------------------------------------------------------------------------------------------------

    bzoj3674可持久化并查集加强版

    题意:

    同3673,但强制在线且点数操作数≤200000

    题解:

    T个不停,后来看黄学长博客把数组n*2(log2n)开成结果A了,后来突然明白我fa数组和dep数组是分开维护的,也就是说每次操作新建了两条路径,当然要*2,QAQ~

    代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #define maxn 200010
     5 #define inc(i,j,k) for(int i=j;i<=k;i++)
     6 using namespace std;
     7 
     8 int fa[maxn*50],ch[maxn*50][2],dep[maxn*50],pos[maxn*50],sz,n,m,rt[maxn];
     9 inline int read(){
    10     char ch=getchar(); int f=1,x=0;
    11     while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();} while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
    12     return f*x;
    13 }
    14 void build(int &x,int l,int r){
    15     x=++sz; if(l==r){fa[x]=l; dep[x]=1; pos[x]=l; return;}
    16     int mid=(l+r)>>1; build(ch[x][0],l,mid); build(ch[x][1],mid+1,r);
    17 }
    18 void updatefa(int &x,int l,int r,int a,int b){
    19     sz++; fa[sz]=fa[x]; dep[sz]=dep[x]; pos[sz]=pos[x]; ch[sz][0]=ch[x][0]; ch[sz][1]=ch[x][1];
    20     x=sz; if(l==r){fa[x]=b; return;}
    21     int mid=(l+r)>>1; if(a<=mid)updatefa(ch[x][0],l,mid,a,b);else updatefa(ch[x][1],mid+1,r,a,b);
    22 }
    23 void updatedep(int &x,int l,int r,int a,int b){
    24     sz++; fa[sz]=fa[x]; dep[sz]=dep[x]; pos[sz]=pos[x]; ch[sz][0]=ch[x][0]; ch[sz][1]=ch[x][1];
    25     x=sz; if(l==r){dep[x]=b; return;}
    26     int mid=(l+r)>>1; if(a<=mid)updatedep(ch[x][0],l,mid,a,b);else updatedep(ch[x][1],mid+1,r,a,b);
    27 }
    28 int query(int x,int l,int r,int a){
    29     if(l==r)return x; int mid=(l+r)>>1;
    30     if(a<=mid)return query(ch[x][0],l,mid,a);else return query(ch[x][1],mid+1,r,a);
    31 }
    32 int find(int x,int y){
    33     int z=query(x,1,n,y); if(fa[z]==pos[z])return z;else return find(x,fa[z]);
    34 }
    35 void merge(int &s,int x,int y){
    36     int z1=find(s,x),z2=find(s,y); if(pos[z1]==pos[z2])return; if(dep[z1]>dep[z2])swap(z1,z2);
    37     int abc=max(dep[z2],dep[z1]+1); updatefa(s,1,n,pos[z1],pos[z2]); updatedep(s,1,n,pos[z2],abc);
    38 }
    39 int main(){
    40     n=read(); m=read(); build(rt[0],1,n); int last=0;
    41     inc(i,1,m){
    42         int opt=read();
    43         if(opt==1){int a=read()^last,b=read()^last; rt[i]=rt[i-1]; merge(rt[i],a,b);}
    44         if(opt==2){int k=read()^last; rt[i]=rt[k];}
    45         if(opt==3){
    46             int a=read()^last,b=read()^last; rt[i]=rt[i-1];
    47             if(pos[find(rt[i],a)]==pos[find(rt[i],b)])puts("1"),last=1;else puts("0"),last=0;
    48         }
    49     }
    50     return 0;
    51 }

    20160623

  • 相关阅读:
    ILM --interface logic model
    dbGet net trace instant pin
    LIST 列表
    Getopt::Long
    TCL Strings
    MBA 报考
    英语 口译考试
    微服务了解
    解析微服务架构(三):微服务重构应用及IBM解决方案
    解析微服务架构(二):融入微服务的企业集成架构
  • 原文地址:https://www.cnblogs.com/YuanZiming/p/5701115.html
Copyright © 2011-2022 走看看