大概就是维护一个关于fa的可持久化数组,发现中间的节点好浪费啊233,但是好像也没有其他办法了。
注意最好不要写路径压缩,不但麻烦,而且慢。
还有就是BZOJ3674那个记录lt,rt值会MLE,以后还是函数中直接控制范围为妙啊哈哈
BZOJ 3673
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=(int)2*1e5+10;
struct tree
{
int lt,rt,lson,rson,fa;
}t[maxn<<4];
int cnt,n,m;
int root[maxn];
inline int read()
{
int x=0;char ch=getchar();
while(ch<'0'||ch>'9')ch=getchar();
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x;
}
void build(int &ro,int l,int r)
{
ro=++cnt;
t[ro].lt=l;
t[ro].rt=r;
if(l==r)
{
t[ro].fa=l;
return ;
}
int mid=(l+r)>>1;
build(t[ro].lson,l,mid);
build(t[ro].rson,mid+1,r);
}
void update(int pre,int &ro,int pos,int fa)
{
ro=++cnt;
t[ro]=t[pre];
if(t[ro].lt==t[ro].rt)
{
t[ro].fa=fa;
return;
}
int mid=(t[ro].lt+t[ro].rt)>>1;
if(pos<=mid) update(t[pre].lson,t[ro].lson,pos,fa);
else update(t[pre].rson,t[ro].rson,pos,fa);
}
int query(int ro,int pos)
{
if(t[ro].lt==t[ro].rt)return t[ro].fa;
int mid=(t[ro].lt+t[ro].rt)>>1;
if(pos<=mid)return query(t[ro].lson,pos);
else return query(t[ro].rson,pos);
}
int find(int ro,int x)
{
int fa=query(ro,x);
return x==fa?x:find(ro,fa);
}
int main()
{
n=read();
m=read();
int d;
build(root[0],1,n);
for(int i=1;i<=m;i++)
{
d=read();
root[i]=root[i-1];
if(d==1)
{
int a=read(),b=read();
a=find(root[i],a);
b=find(root[i],b);
if(a==b)continue;
update(root[i],root[i],b,a);
}
else if(d==2)root[i]=root[read()];
else
printf("%d\n",(find(root[i],read())==find(root[i],read())));
}
}
BZOJ 3674
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=2*1e5+10;
struct tree
{
int lson,rson,fa;
}t[maxn*100];
int cnt,n,m;
int root[maxn];
inline int read()
{
int x=0;char ch=getchar();
while(ch<'0'||ch>'9')ch=getchar();
while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
return x;
}
void build(int &ro,int l,int r)
{
ro=++cnt;
if(l==r)
{
t[ro].fa=l;
return;
}
int mid=(l+r)>>1;
build(t[ro].lson,l,mid);
build(t[ro].rson,mid+1,r);
}
void update(int pre,int &ro,int pos,int fa,int l,int r)
{
ro=++cnt;
t[ro]=t[pre];
if(l==r)
{
t[ro].fa=fa;
return;
}
int mid=(l+r)>>1;
if(pos<=mid) update(t[pre].lson,t[ro].lson,pos,fa,l,mid);
else update(t[pre].rson,t[ro].rson,pos,fa,mid+1,r);
}
int query(int ro,int pos,int l,int r)
{
if(l==r)return t[ro].fa;
int mid=(l+r)>>1;
if(pos<=mid)return query(t[ro].lson,pos,l,mid);
else return query(t[ro].rson,pos,mid+1,r);
}
int find(int ro,int x)
{
int fa=query(ro,x,1,n);
return x==fa?x:find(ro,fa);
}
int main()
{
n=read();
m=read();
int d,last=0;
build(root[0],1,n);
for(int i=1;i<=m;i++)
{
d=read();
root[i]=root[i-1];
if(d==1)
{
int a=read()^last,b=read()^last;
a=find(root[i],a);
b=find(root[i],b);
if(a==b)continue;
update(root[i],root[i],b,a,1,n);
}
else if(d==2)root[i]=root[read()^last];
else
printf("%d\n",last=(find(root[i],read()^last)==find(root[i],read()^last)));
}
}