zoukankan      html  css  js  c++  java
  • 【BZOJ】【3673】可持久化并查集 & 【3674】可持久化并查集加强版

    可持久化并查集


      Orz hzwer & zyf

      呃学习了一下可持久化并查集的姿势……其实并查集就是一个fa数组(可能还要带一个size或rank数组),那么我们对并查集可持久化其实就是实现一个可持久化数组……

      那么我们用可持久化线段树实现一下可持久化数组就可以了- -

      一开始我比较傻逼,想着:中间的叶子节点不是没用嘛?什么信息也不存……然而如果不这样的话,难道你每次修改,新建N个指针吗?这样可以保证每次只新建O(logn)个节点出来……

      (是不是a+b problem也是类似的原因?并不知道诶……去做下看看好了)

      嘛那么这里维护一下fa和size就可以了。。。

      1 /**************************************************************
      2     Problem: 3673
      3     User: Tunix
      4     Language: C++
      5     Result: Accepted
      6     Time:64 ms
      7     Memory:7608 kb
      8 ****************************************************************/
      9  
     10 //BZOJ 3673
     11 #include<cstdio>
     12 #include<cstring>
     13 #include<cstdlib>
     14 #include<iostream>
     15 #include<algorithm>
     16 #define rep(i,n) for(int i=0;i<n;++i)
     17 #define F(i,j,n) for(int i=j;i<=n;++i)
     18 #define D(i,j,n) for(int i=j;i>=n;--i)
     19 #define pb push_back
     20 using namespace std;
     21 typedef long long LL;
     22 inline int getint(){
     23     int r=1,v=0; char ch=getchar();
     24     for(;!isdigit(ch);ch=getchar()) if (ch=='-') r=-1;
     25     for(; isdigit(ch);ch=getchar()) v=v*10-'0'+ch;
     26     return r*v;
     27 }
     28 const int N=2e4+10;
     29 /*******************template********************/
     30  
     31 int n,m,cnt,rt[N];
     32  
     33 struct node{
     34     int l,r,v,size;
     35 }t[N*20];
     36 #define L t[o].l
     37 #define R t[o].r
     38 #define mid (l+r>>1)
     39 #define lch L,l,mid
     40 #define rch R,mid+1,r
     41  
     42 void build(int &o,int l,int r){
     43     o=++cnt;
     44     if (l==r) {t[o].v=l;t[o].size=1;return;}
     45     build(lch);
     46     build(rch);
     47 }
     48 void update(int &o,int l,int r,int pos,int v){
     49     t[++cnt]=t[o], o=cnt;
     50     if (l==r) {t[o].v=v; return;}
     51     if (pos<=mid) update(lch,pos,v);
     52     else update(rch,pos,v);
     53 }
     54 void modify(int &o,int l,int r,int pos,int v){
     55     t[++cnt]=t[o], o=cnt;
     56     if (l==r) {t[o].size+=v; return;}
     57     if (pos<=mid) modify(lch,pos,v);
     58     else modify(rch,pos,v);
     59 }
     60 int queryv(int o,int l,int r,int pos){
     61     if (l==r) return t[o].v;
     62     if (pos<=mid) return queryv(lch,pos);
     63     else return queryv(rch,pos);
     64 }
     65 int querysz(int o,int l,int r,int pos){
     66     if (l==r) return t[o].size;
     67     if (pos<=mid) return querysz(lch,pos);
     68     else return querysz(rch,pos);
     69 }
     70 int getfa(int x,int y){
     71     int now=y,nxt=queryv(rt[x],1,n,y);
     72     while(now!=nxt){
     73         now=nxt;
     74         nxt=queryv(rt[x],1,n,now);
     75     }
     76     return now;
     77 }
     78  
     79 int main(){
     80 #ifndef ONLINE_JUDGE
     81     freopen("3673.in","r",stdin);
     82     freopen("3673.out","w",stdout);
     83 #endif
     84     n=getint(); m=getint();
     85     build(rt[0],1,n);
     86     int cmd,x,y,ans=0;
     87     F(i,1,m){
     88         rt[i]=rt[i-1];
     89         cmd=getint();
     90         if (cmd==1){
     91             x=getint(); y=getint();
     92             int f1=getfa(i,x),f2=getfa(i,y),
     93                 s1=querysz(rt[i],1,n,f1),s2=querysz(rt[i],1,n,f2);
     94             if (s1<s2) swap(f1,f2);
     95             modify(rt[i],1,n,f1,s2);
     96             update(rt[i],1,n,f2,f1);
     97         }else if (cmd==2){
     98             rt[i]=rt[getint()];
     99         }else if (cmd==3){
    100             x=getint(); y=getint();
    101             int f1=getfa(i,x),f2=getfa(i,y);
    102             printf("%d
    ",ans=(f1==f2));
    103         }
    104     }       
    105     return 0;
    106 }
    View Code(3673)
      1 /**************************************************************
      2     Problem: 3674
      3     User: Tunix
      4     Language: C++
      5     Result: Accepted
      6     Time:1336 ms
      7     Memory:158308 kb
      8 ****************************************************************/
      9  
     10 //BZOJ 3674
     11 #include<cstdio>
     12 #include<cstring>
     13 #include<cstdlib>
     14 #include<iostream>
     15 #include<algorithm>
     16 #define rep(i,n) for(int i=0;i<n;++i)
     17 #define F(i,j,n) for(int i=j;i<=n;++i)
     18 #define D(i,j,n) for(int i=j;i>=n;--i)
     19 #define pb push_back
     20 using namespace std;
     21 typedef long long LL;
     22 inline int getint(){
     23     int r=1,v=0; char ch=getchar();
     24     for(;!isdigit(ch);ch=getchar()) if (ch=='-') r=-1;
     25     for(; isdigit(ch);ch=getchar()) v=v*10-'0'+ch;
     26     return r*v;
     27 }
     28 const int N=2e5+10;
     29 /*******************template********************/
     30  
     31 int n,m,cnt,rt[N];
     32  
     33 struct node{
     34     int l,r,v,size;
     35 }t[10000010];
     36 #define L t[o].l
     37 #define R t[o].r
     38 #define mid (l+r>>1)
     39 #define lch L,l,mid
     40 #define rch R,mid+1,r
     41  
     42 void build(int &o,int l,int r){
     43     o=++cnt;
     44     if (l==r) {t[o].v=l;t[o].size=1;return;}
     45     build(lch);
     46     build(rch);
     47 }
     48 void update(int &o,int l,int r,int pos,int v){
     49     t[++cnt]=t[o], o=cnt;
     50     if (l==r) {t[o].v=v; return;}
     51     if (pos<=mid) update(lch,pos,v);
     52     else update(rch,pos,v);
     53 }
     54 void modify(int &o,int l,int r,int pos,int v){
     55     t[++cnt]=t[o], o=cnt;
     56     if (l==r) {t[o].size+=v; return;}
     57     if (pos<=mid) modify(lch,pos,v);
     58     else modify(rch,pos,v);
     59 }
     60 int queryv(int o,int l,int r,int pos){
     61     if (l==r) return t[o].v;
     62     if (pos<=mid) return queryv(lch,pos);
     63     else return queryv(rch,pos);
     64 }
     65 int querysz(int o,int l,int r,int pos){
     66     if (l==r) return t[o].size;
     67     if (pos<=mid) return querysz(lch,pos);
     68     else return querysz(rch,pos);
     69 }
     70 int getfa(int x,int y){
     71     int now=y,nxt=queryv(rt[x],1,n,y);
     72     while(now!=nxt){
     73         now=nxt;
     74         nxt=queryv(rt[x],1,n,now);
     75     }
     76     return now;
     77 }
     78  
     79 int main(){
     80 #ifndef ONLINE_JUDGE
     81     freopen("3674.in","r",stdin);
     82     freopen("3674.out","w",stdout);
     83 #endif
     84     n=getint(); m=getint();
     85     build(rt[0],1,n);
     86     int cmd,x,y,ans=0;
     87     F(i,1,m){
     88         rt[i]=rt[i-1];
     89         cmd=getint();
     90         if (cmd==1){
     91             x=getint()^ans; y=getint()^ans;
     92             int f1=getfa(i,x),f2=getfa(i,y),
     93                 s1=querysz(rt[i],1,n,f1),s2=querysz(rt[i],1,n,f2);
     94             if (s1<s2) swap(f1,f2);
     95             modify(rt[i],1,n,f1,s2);
     96             update(rt[i],1,n,f2,f1);
     97         }else if (cmd==2){
     98             rt[i]=rt[getint()^ans];
     99         }else if (cmd==3){
    100             x=getint()^ans; y=getint()^ans;
    101             int f1=getfa(i,x),f2=getfa(i,y);
    102             printf("%d
    ",ans=(f1==f2));
    103         }
    104     }       
    105     return 0;
    106 }
    View Code(3674)

    (3674为强制在线,且数据范围20W)

    3673: 可持久化并查集 by zky

    Time Limit: 5 Sec  Memory Limit: 128 MB
    Submit: 757  Solved: 319
    [Submit][Status][Discuss]

    Description

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

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

    Input

    Output

    Sample Input

    5 6
    1 1 2
    3 1 2
    2 0
    3 1 2
    2 1
    3 1 2

    Sample Output

    1
    0
    1




    HINT

    Source

    [Submit][Status][Discuss]
  • 相关阅读:
    jmeter调试-webservise服务直接HTTP请求--方式一
    jmeter-webservise服务HTTP信息头管理器方式--方式二
    使用SoupUI工具获得webservise服务的请求格式内容
    SOUPUI安装破解-小白看
    Jmeter-插件扩展及性能监控插件的安装
    jmeter-命令行执行及测试报告导出
    类加载过程
    老生常谈:String s1 = new String("abc") 创建了几个字符串对象及8 种基本类型的包装类和常量池
    mysql的日期时间类型格式
    leetCode 您正在爬楼梯。它需要n步才能到达顶部。每次您可以爬1或2步。您可以通过几种不同的方式登顶?
  • 原文地址:https://www.cnblogs.com/Tunix/p/4587626.html
Copyright © 2011-2022 走看看