TLE 88pts 求助 悬赏2关注
查看原帖
TLE 88pts 求助 悬赏2关注
134510
WrongAnswer_90Alive楼主2023/7/7 08:21

我开了两个可持久化线段树,一个用来维护fa,另一个用来维护子树大小,但是T了3个点

是做法假了吗。。。

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
#include<stack>
using namespace std;
inline int read()
{
	int ans=0;char ch=getchar();
	while((ch>'9')||(ch<'0'))ch=getchar();
	while((ch>='0')&&(ch<='9'))ans=ans*10+ch-'0',ch=getchar();
	return ans;
}
struct Segment{int ls,rs,val;}t[3200001],t2[3200001];
int root[200001],n,m,cnt,cnt2;
int build(int l,int r)
{
	int mid=l+((r-l)>>1),nw=++cnt;
	if(l==r)t[nw].val=l;
	else t[nw].ls=build(l,mid),t[nw].rs=build(mid+1,r);
	return nw;
}
int build2(int l,int r)
{
	int mid=l+((r-l)>>1),nw=++cnt2;
	if(l==r)t2[nw].val=1;
	else t2[nw].ls=build2(l,mid),t2[nw].rs=build2(mid+1,r);
	return nw;
}
int change(int from,int l,int r,int x,int y)
{
	int nw=++cnt,mid=l+((r-l)>>1);
	if(l==r){t[nw].val=y;return nw;}
	if(x<=mid)t[nw].rs=t[from].rs,t[nw].ls=change(t[from].ls,l,mid,x,y);
	else t[nw].ls=t[from].ls,t[nw].rs=change(t[from].rs,mid+1,r,x,y);
	return nw;
}
int change2(int from,int l,int r,int x,int y)
{
	int nw=++cnt2,mid=l+((r-l)>>1);
	if(l==r){t2[nw].val+=y;return nw;}
	if(x<=mid)t2[nw].rs=t2[from].rs,t2[nw].ls=change2(t2[from].ls,l,mid,x,y);
	else t2[nw].ls=t2[from].ls,t2[nw].rs=change2(t2[from].rs,mid+1,r,x,y);
	return nw;
}
int ask(int nw,int l,int r,int x)
{
	int mid=l+((r-l)>>1);
	if(l==r)return t[nw].val;
	if(x<=mid)return ask(t[nw].ls,l,mid,x);
	return ask(t[nw].rs,mid+1,r,x);
}
int ask2(int nw,int l,int r,int x)
{
	int mid=l+((r-l)>>1);
	if(l==r)return t2[nw].val;
	if(x<=mid)return ask2(t2[nw].ls,l,mid,x);
	return ask2(t2[nw].rs,mid+1,r,x);
}
int find(int nw,int x)
{
	int k=ask(nw,1,n,x);
	return k==x?x:find(nw,k);
}
void merge(int rt,int nw,int x,int y)
{
	x=find(rt,x),y=find(rt,y);
	int sizx=ask2(rt,1,n,x),sizy=ask2(rt,1,n,y);
	if(sizx>sizy)
	{
		root[nw]=change(rt,1,n,y,x);
		change2(rt,1,n,x,sizy);
	}
	else
	{
		root[nw]=change(rt,1,n,x,y);
		change2(rt,1,n,y,sizx);
	}
}
signed main()
{
	n=read(),m=read();int opt,x,y;
	root[0]=build(1,n);
	for(int i=1;i<=m;++i)
	{
		opt=read();
		switch(opt)
		{
			case 1:x=read(),y=read(),merge(root[i-1],i,x,y);break;
			case 2:x=read(),root[i]=root[x];break;
			case 3:x=read(),y=read(),root[i]=root[i-1];cout<<(find(root[i],x)==find(root[i],y))<<"\n";break;
		}
	}
	return 0;
}
2023/7/7 08:21
加载中...