求助,我的代码要反过来合并
查看原帖
求助,我的代码要反过来合并
239458
cmach_socket楼主2024/1/25 12:18

按照oi wiki,我的代码第81行应该写成82行的样子,然而会TLE 72分;将fa与fb交换写成81行的样子才能AC。说明我的可持久化并查集需要将大的树挂到小的树上???

#include<stdio.h>
#include<algorithm>
#define MAXN 2000005
using namespace std;
class node{
	public:
		int l,r,w,d;
}t[MAXN*4];
int n,m,rt[MAXN],cnt,ta,tb,tk,op,now,fa,fb,da,db;
int build(int l,int r){
	int k=++cnt;
	if(l==r){
		t[k].w=l;t[k].d=1;
		return k;
	}
	int mid=(l+r)>>1;
	t[k].l=build(l,mid);
	t[k].r=build(mid+1,r);
	return k;
}
int ch_fa(int k,int l,int r,int s,int y){
	int nod=++cnt;
	t[nod].l=t[k].l;t[nod].r=t[k].r;t[nod].w=t[k].w;t[nod].d=t[k].d;
	if(l==r){
		t[nod].w=y;
		return nod;
	}
	int mid=(l+r)>>1;
	if(s<=mid)t[nod].l=ch_fa(t[k].l,l,mid,s,y);
	else t[nod].r=ch_fa(t[k].r,mid+1,r,s,y);
	return nod;
}
void ch_dep(int k,int l,int r,int s,int y){
	if(l==r){
		t[k].d=max(t[k].d,y);
		return ;
	}
	int mid=(l+r)>>1;
	if(s<=mid)ch_dep(t[k].l,l,mid,s,y);
	else ch_dep(t[k].r,mid+1,r,s,y);
	return ;
}
int ask_fa(int k,int l,int r,int s){
	if(l==r){
		return t[k].w;
	}
	int mid=(l+r)>>1;
	if(s<=mid)return ask_fa(t[k].l,l,mid,s);
	else return ask_fa(t[k].r,mid+1,r,s);
}
int ask_dep(int k,int l,int r,int s){
	if(l==r){
		return t[k].d;
	}
	int mid=(l+r)>>1;
	if(s<=mid)return ask_fa(t[k].l,l,mid,s);
	else return ask_fa(t[k].r,mid+1,r,s);
}
int findd(int k,int s){
	int f=ask_fa(k,1,n,s);
	if(s==f)return f;
	return findd(k,f);
}
int main(){
	//freopen("P3402_1.in","r",stdin);
	//freopen("P3402.out","w",stdout);
	scanf("%d%d",&n,&m);
	rt[0]=build(1,n);
	for(int i=1;i<=m;i++){
		scanf("%d",&op);
		if(op==1){
			scanf("%d%d",&ta,&tb);
			fa=findd(rt[i-1],ta);
			fb=findd(rt[i-1],tb);
			if(fa!=fb){
				da=ask_dep(rt[i-1],1,n,fa);
				db=ask_dep(rt[i-1],1,n,fb);
				if(da>db){
					swap(fa,fb);swap(da,db);
				}//现在fa较小
				rt[i]=ch_fa(rt[i-1],1,n,fb,fa);
				//小的父亲是大的 rt[i]=ch_fa(rt[i-1],1,n,fa,fb)
				ch_dep(rt[i],1,n,fa,db+1);
			}
			else rt[i]=rt[i-1];
		}
		else if(op==2){
			scanf("%d",&tk);
			rt[i]=rt[tk];
		}
		else if(op==3){
			scanf("%d%d",&ta,&tb);
			//printf("%d %d %d df\n",i-1,findd(rt[i-1],ta),findd(rt[i-1],tb));
			if(findd(rt[i-1],ta)==findd(rt[i-1],tb)){
				puts("1");
			}
			else puts("0");
			rt[i]=rt[i-1];
		}
	}
	return 0;
}
2024/1/25 12:18
加载中...