求助板子,可持久化并查集
查看原帖
求助板子,可持久化并查集
342487
BreakPlus楼主2022/7/20 16:00

RT,死活找不到错

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,m,opt,x,y,root[1000005],cnt;
struct Node{
	ll ls,rs,val,dep;
}node[10000005];
ll build(ll l,ll r){
	ll pos=(++cnt);
	if(l==r){
		node[pos].val=l;
		return pos;
	}
	ll mid=l+r>>1;
	if(l<=mid) node[pos].ls=build(l,mid);
	if(mid<r)  node[pos].rs=build(mid+1,r);
	return pos;
}
ll update(ll before,ll l,ll r,ll s,ll t){
	ll pos=(++cnt);
	if(l==r){
		node[pos].val=t;
		node[pos].dep=node[before].dep;
		return pos;
	}
	ll mid=l+r>>1;
	if(s<=mid){
		node[pos].rs=node[before].rs;
		node[pos].ls=update(node[before].ls,l,mid,s,t);
	} else {
		node[pos].ls=node[before].ls;
		node[pos].rs=update(node[before].rs,mid+1,r,s,t);
	}
	return pos;
}
void add(ll l,ll r,ll w,ll pos){
	if(l==r){
		node[pos].dep++;
		return;
	}
	ll mid=l+r>>1;
	if(w<=mid) add(l,mid,w,node[pos].ls);
	else add(mid+1,r,w,node[pos].rs);
}
ll query(ll need,ll l,ll r,ll pos){
	if(l==r) return pos;
	ll mid=l+r>>1;
	if(need<=mid) return query(need,l,mid,node[pos].ls);
	else return query(need,mid+1,r,node[pos].rs);
}
ll find(ll x,ll cur){
	ll w=query(x,1,n,root[cur]);
	if(x==node[w].val) return w;
	return find(node[w].val,cur);
}
void Merge(ll x,ll y,ll cur){
	ll fx=find(x,cur-1), fy=find(y,cur-1);
	if(node[fx].val==node[fy].val) return;
	ll depx=node[fx].dep, depy=node[fy].dep;
	if(depx>depy) swap(fx,fy);
	root[cur]=update(root[cur-1],1,n,node[fx].val,node[fy].val);
	if(depx==depy) add(1,n,node[fy].val,root[cur]); 
} 
int main(){
	cin>>n>>m;
	root[0]=build(1,n);
	for(ll i=1;i<=m;i++){
		cin>>opt;
		if(opt==1){
			cin>>x>>y; Merge(x,y,i);
		}else if(opt==2) cin>>x, root[i]=root[x];
		else cin>>x>>y, root[i]=root[i-1], cout<<(node[find(x,i)].val==node[find(y,i)].val)<<endl;
	} 
	return 0;
}
2022/7/20 16:00
加载中...