• bzoj3674: 可持久化并查集加强版


    Description:
    自从zkysb出了可持久化并查集后……
    hzwer:乱写能AC,暴力踩标程
    KuribohG:我不路径压缩就过了!
    ndsf:暴力就可以轻松虐!
    zky:……

    n个集合 m个操作
    操作:
    1 a b 合并a,b所在集合
    2 k 回到第k次操作之后的状态(查询算作操作)
    3 a b 询问a,b是否属于同一集合,是则输出1否则输出0
    请注意本题采用强制在线,所给的a,b,k均经过加密,加密方法为x = x xor lastans,lastans的初始值为0
    0<n,m<=2*10^5


    Input

     

    Output

     

    Sample Input

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

    Sample Output

    1
    0
    1
    这里用到了主席树的一个性质:支持历史版本的操作,我们用主席树在每个点上表示它的祖先,感觉有点浪费,反正瞎搞就过了
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    typedef long long ll;
    
    int bh, n, tn, m, l, r, G, a, b, cases;
    int root[200010];
    int Hash[200010];
    struct NODe{
          int lson, rson, val;
    }tree[200010 * 100];
    
    void build(int &u,int l, int r) {
         u=bh++;
          if(l==r) 
        {
            tree[u].val=0;
            return;
          }
          int mid=(l+r)>>1;
          build(tree[u].lson,l,mid);
          build(tree[u].rson,mid+1,r);
    }
    
    /*int update(int i, int l, int r, int old, int val) {
          if (l == r) {
            bh++;
            tree[bh].val = val;
            return bh;
          }
          int tbh;
          int mid = (l + r) >> 1;
          if (i > mid) {
            bh++;
            tbh = bh;
            tree[bh].lson = tree[old].lson;
            tree[tbh].rson = update(i, mid + 1, r, tree[old].rson, val);
          } else {
            bh++;
            tbh = bh;
            tree[bh].rson = tree[old].rson;
            tree[tbh].lson = update(i, l, mid, tree[old].lson, val);
          }
      // printf("%d %d %d %d", i, l, r, old);
      // printf(" change->%d
    ", tbh);
      // printf("lson=%d rson=%d
    ", tree[tbh].lson, tree[tbh].rson);
          return tbh;
    }*/
    void update(int l,int r,int &x,int y,int pos,int val)
    {
        if(l==r)
        {
            x=bh++;
            tree[x].val=val;
            return;
        }
        int mid=(l+r)>>1;
        if(pos>mid)
        {
            x=bh++;
            tree[x].lson=tree[y].lson;
            update(mid+1,r,tree[x].rson,tree[y].rson,pos,val);
        }else
        {
            x=bh++;
            tree[x].rson=tree[y].rson;
            update(l,mid,tree[x].lson,tree[y].lson,pos,val);
        }
    }
    int query(int rt, int wz, int l, int r) {
          if(l == r){
            return tree[rt].val;
          }    
          int mid = (l + r) / 2;
          if (wz <= mid) {
            return query(tree[rt].lson, wz, l, mid);
          }else{
            return query(tree[rt].rson, wz, mid + 1, r);
          }
    }
    int get_father(int rt,int x,int i) 
    {
          int tmp=query(rt,x,1,n);
          if (tmp==0)
            return x;
          int fa=get_father(rt,tmp,i);
          update(1,n,root[i],root[i],x,fa);
          return fa;
    }
    
    int main() {
          scanf("%d%d", &n, &m);
          build(root[0],1,n);
          int lastans = 0;
          for (int i = 1; i <= m; i++) {
            scanf("%d", &cases);
            if (cases == 1) {
              scanf("%d%d", &a, &b);
              a = a ^ lastans;
              b = b ^ lastans;
              root[i] = root[i - 1];
              int fax = get_father(root[i], a, i);
              int fay = get_father(root[i], b, i);
              if (fax != fay) {
                update(1, n,root[i], root[i],fax, fay);
                  }
            } else if (cases == 2) {
            scanf("%d", &a);
            a = a ^ lastans;
              root[i] = root[a];
        } else {
              scanf("%d%d", &a, &b);
              a = a ^ lastans;
              b = b ^ lastans;
              root[i] = root[i - 1];
              int fax = get_father(root[i], a, i);
              int fay = get_father(root[i], b, i);
          // printf("%d %d %d %d
    ", a, fax, b, fay);
              if (fax == fay) {
                lastans = 1;
              } else {
                lastans = 0;
              }
              printf("%d
    ", lastans);
        }
      }
      //system("pause");
      return 0;
    }

    个人觉得我的代码比hgz的精简吧

    此题还能用rope瞎搞

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<ext/rope>
    using namespace std;
    using namespace __gnu_cxx;
    #define maxn 200010
    rope<int> *rp[maxn];
    int a[maxn];
    int findrep(int i,int x)
    {
        if(rp[i]->at(x)==x) return x;
        int f=findrep(i,rp[i]->at(x));
        if (f==rp[i]->at(x)) return f;
        rp[i]->replace(x,f);
        return f;
    }
    int main()
    {
        int n,m;
        scanf("%d %d",&n,&m);
        int x,y,lastans=0,Mode;
        for(int i=1;i<=n;i++)
        a[i]=i; 
        rp[0]=new rope<int> (a,a+n+1); 
        for(int i=1;i<=m;i++)
        {
            rp[i]=new rope<int> (*rp[i-1]);
            scanf("%d",&Mode);
            if(Mode==1)
            {
                scanf("%d %d",&x,&y);
                x^=lastans;
                y^=lastans;
                int fx=findrep(i,x),fy=findrep(i,y);
                if(fx!=fy)
                {
                    rp[i]->replace(fy,fx);
                }
            }else
            if(Mode==2)
            {
                scanf("%d",&x);
                x^=lastans;
                rp[i]=rp[x];
            }else
            {
                int a,b;
                scanf("%d %d",&a,&b);
                a^=lastans,b^=lastans;
                printf("%d
    ",lastans=(findrep(i,a)==findrep(i,b)));
            }
        }
        return 0;
     } 
  • 相关阅读:
    字符数组+数组复习
    C语言博客作业05-指针
    C语言博客作业04 数组
    C语言博客作业03 函数
    Java与C# socket通信
    JDBC复制数据库(sqlite)
    mysql Connector/net不能更新或删除(转载)
    MATLAB回归、插值、逼近、拟合【转载】
    前端请求RestController发送数据方法汇总
    elementUI el-input 输入框 设置高度和宽度
  • 原文地址:https://www.cnblogs.com/dancer16/p/7528847.html
Copyright © 2020-2023  润新知