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\n",lastans);
        }
    }
}
posted @ 2016-05-03 22:49  qscqesze  阅读(521)  评论(0编辑  收藏  举报