zoukankan      html  css  js  c++  java
  • BZOJ 3673/BZOJ 3674 可持久化并查集

    =可持久化数组。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define maxn 200050
    using namespace std;
    int n,m,type,a,b,tot=0,root[maxn],ls[maxn*50],rs[maxn*50],dis[maxn*50],fath[maxn*50],last=0;
    void build(int &now,int left,int right)
    {
        now=++tot;
        if (left==right) {fath[now]=left;return;}
        int mid=(left+right)>>1;
        build(ls[now],left,mid);
        build(rs[now],mid+1,right);
    }
    int query(int now,int left,int right,int pos)
    {
        if (left==right) return now;
        int mid=(left+right)>>1;
        if (pos<=mid) return query(ls[now],left,mid,pos);
        else return query(rs[now],mid+1,right,pos);
    }
    void modify(int last,int &now,int left,int right,int pos,int x)
    {
        now=++tot;
        if (left==right) {fath[now]=x;return;}
        int mid=(left+right)>>1;ls[now]=ls[last];rs[now]=rs[last];
        if (pos<=mid) modify(ls[last],ls[now],left,mid,pos,x);
        else modify(rs[last],rs[now],mid+1,right,pos,x);
    }
    void add(int now,int left,int right,int pos)
    {
        if (left==right) {dis[now]++;return;}
        int mid=(left+right)>>1;
        if (pos<=mid) add(ls[now],left,mid,pos);
        else add(rs[now],mid+1,right,pos);
    }
    int find(int now,int x)
    {
        int v=query(now,1,n,x);
        if (fath[v]==x) return v;
        return find(now,fath[v]);
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        build(root[0],1,n);
        for (int i=1;i<=m;i++)
        {
            scanf("%d",&type);
            if (type==1)
            {
                scanf("%d%d",&a,&b);a^=last;b^=last;root[i]=root[i-1];
                int p=find(root[i],a),q=find(root[i],b);
                if (p==q) continue;
                if (dis[p]>dis[q]) swap(p,q);
                modify(root[i-1],root[i],1,n,fath[p],fath[q]);
                if (dis[p]==dis[q]) add(root[i],1,n,fath[q]);
            }
            else if (type==2) {scanf("%d",&a);a^=last;root[i]=root[a];}
            else
            {
                scanf("%d%d",&a,&b);a^=last;b^=last;root[i]=root[i-1];
                int p=find(root[i],a),q=find(root[i],b);
                last=(fath[p]==fath[q]);printf("%d
    ",last);
            }
        }
        return 0;
    }
  • 相关阅读:
    剑指offer 39. 是否为平衡二叉树
    剑指offer 38. 二叉树的深度
    剑指offer 16. 合并两个有序链表
    剑指offer 15.链表反转
    剑指offer 58.对称的二叉树
    剑指offer 62. 二叉搜索树的第 k 个结点
    二叉树的前序和中序遍历的非递归实现
    将求模运算转换成与运算,加快运算速度
    Java中数字的格式化输出
    Java中的freopen()
  • 原文地址:https://www.cnblogs.com/ziliuziliu/p/6519967.html
Copyright © 2011-2022 走看看