BZOJ 3673/BZOJ 3674 可持久化并查集

Posted on 2017-03-08 16:18  ziliuziliu  阅读(95)  评论(0编辑  收藏  举报

=可持久化数组。

#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\n",last);
        }
    }
    return 0;
}