您的位置:首页 > 其它

【BZOJ】3673: 可持久化并查集 by zky

2017-01-19 23:42 288 查看
传送门 http://www.lydsy.com/JudgeOnline/problem.php?id=3673

可持久化数据结构去搞下father数组就好

我写了线段树,除了叶子什么都不维护,树的形态只供路径的导向

#include<stdio.h>
#include<algorithm>
#define N 20005
using namespace std;

struct tree{int f,s,lson,rson;}t[N<<5];

int n,m,c2,tot,fu,fv,aim,s1,s2,type,u,v,Rt
;
bool flag;

void build(int &k,const int &l,const int &r)
{
k=++tot;
if (l==r){t[k]=(tree){l,1,0,0};return;}
int mid=l+r>>1;
build(t[k].lson,l,mid);
build(t[k].rson,mid+1,r);
}

int fa(const int &k,const int &l,const int &r)
{
if (l==r)
{
aim=t[k].f;
if (t[k].f==l) flag=1;
return t[k].s;
}
int mid=l+r>>1,rt;
while (!flag && l<=aim && aim<=r) rt=(aim<=mid)?fa(t[k].lson,l,mid):fa(t[k].rson,mid+1,r);
return rt;
}

void change(int &k,const int &l,const int &r)
{
if (!k) k=++tot;
if (l==r){t[k]=(tree){fu,c2,0,0};return;}
int mid=l+r>>1;
if (aim<=mid){change(t[k].lson,l,mid);return;}
change(t[k].rson,mid+1,r);
}

void link(const int &k,const int &lk,const int &l,const int &r)
{
if (l==r) return;
if (!t[k].lson) t[k].lson=t[lk].lson;
if (!t[k].rson) t[k].rson=t[lk].rson;
int mid=l+r>>1;
if (aim<=mid){link(t[k].lson,t[lk].lson,l,mid);return;}
link(t[k].rson,t[lk].rson,mid+1,r);
}

int main()
{
scanf("%d%d",&n,&m);
build(Rt[0],1,n);
for (int i=1;i<=m;i++)
{
scanf("%d",&type);
if (type==1)
{
scanf("%d%d",&u,&v);
flag=0,aim=u,s1=fa(Rt[i-1],1,n),fu=aim;
flag=0,aim=v,s2=fa(Rt[i-1],1,n),fv=aim;
if (fu!=fv)
{
if (s1<s2) swap(fu,fv);
c2=s1+s2,aim=fu,change(Rt[i],1,n);
c2=s2,aim=fv,change(Rt[i],1,n);
aim=fu,link(Rt[i],Rt[i-1],1,n);
aim=fv,link(Rt[i],Rt[i-1],1,n);
}
else Rt[i]=Rt[i-1];
}
if (type==2)
{
scanf("%d",&u);
Rt[i]=Rt[u];
}
if (type==3)
{
scanf("%d%d",&u,&v);
Rt[i]=Rt[i-1];
flag=0,aim=u,s1=fa(Rt[i],1,n),fu=aim;
flag=0,aim=v,s2=fa(Rt[i],1,n),fv=aim;
printf("%d\n",fu==fv?1:0);
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: