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

    3674: 可持久化并查集加强版

    题目连接:

    http://www.lydsy.com/JudgeOnline/problem.php?id=3674

    Description

    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

    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

    Hint

    题意

    题解:

    需要的是可持久化数组,这个用主席树那样子去维护就好了

    并查集什么的,直接莽就好了

    但是要过3673的话,把并查集得改成按秩合并的样子才行吧?

    代码

    #include<stdio.h>
    using namespace std;
    const int maxn = 2e5+7;
    inline int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    struct node
    {
        int l,r,f;
    }T[maxn*100];
    int root[maxn],cnt,n,m,lastans;
    void update(int l,int r,int &x,int pos,int f)
    {
        T[++cnt]=T[x];x=cnt;
        if(l==r)
        {
            T[x].f=f;
            return;
        }
        int mid = (l+r)/2;
        if(pos<=mid)update(l,mid,T[x].l,pos,f);
        else update(mid+1,r,T[x].r,pos,f);
    }
    int query(int l,int r,int x,int pos)
    {
        if(l==r)return T[x].f;
        int mid = (l+r)/2;
        if(pos<=mid)return query(l,mid,T[x].l,pos);
        else return query(mid+1,r,T[x].r,pos);
    }
    int fi(int &x,int a)
    {
        int p=query(1,n,x,a);
        if(p==a)return p;
        int q = fi(x,p);
        update(1,n,x,a,q);
        return q;
    }
    int main()
    {
        n=read(),m=read();
        for(int i=1;i<=n;i++)update(1,n,root[0],i,i);
        for(int i=1;i<=m;i++)
        {
            int op=read();
            root[i]=root[i-1];
            if(op==1)
            {
                int x=read(),y=read();x^=lastans,y^=lastans;
                int fx=fi(root[i],x),fy=fi(root[i],y);
                if(fx!=fy)update(1,n,root[i],fx,fy);
            }
            else if(op==2)
            {
                int x=read();x^=lastans;
                root[i]=root[x];
            }
            else
            {
                int x=read(),y=read();x^=lastans,y^=lastans;
                int fx=fi(root[i],x),fy=fi(root[i],y);
                lastans=(fx==fy);
                printf("%d
    ",lastans);
            }
        }
    }
  • 相关阅读:
    第十二篇 -- 如何向MFC对话框添加菜单
    第十一篇 -- 如何实现MFC窗口的最大化以及控件随最大化
    第二十三篇 -- 学习第二十四天打卡20190715
    第十篇 -- 学习C++宝典2005版
    第二十二篇 -- 学习第二十一天打卡20190711
    修改nginx日志格式为json
    centos7 脚本搭建SVN
    jenkin、SVN、archery集成openLDAP
    centos搭建OPENldap
    matomo 开源网站分析平台
  • 原文地址:https://www.cnblogs.com/qscqesze/p/5456821.html
Copyright © 2011-2022 走看看