可持久化并查集 68 pts TLE 求助
查看原帖
可持久化并查集 68 pts TLE 求助
526895
WYZ20030051楼主2023/12/6 07:11

数组开小时只有 52 pts,改了一下后就改不动了只有 68 pts

#include<iostream>
#include<cstdio>
#include<cmath>
#include<string>
#include<cstring>
#include<algorithm>
#include<cassert>
#include<stack>
#include<queue>
#include<vector>
#include<map>
#include<cstdlib>
#include<set>
using namespace std;
#define ll long long
#define ull unsigned long long
int read()
{
	int x=0,f=1;
	char ch=getchar();
	while(ch<'0' || ch>'9')
	{
		if(ch=='-')
			f=-1;
		ch=getchar();
	}
	while(ch>='0' && ch<='9')
	{
		x=x*10+(ch-'0');
		ch=getchar();
	}
	return x*f;
}
const int MAXN=1e6+10;
int n,m;
struct tree
{
	int dep,fa;
	int ch[2];
}tr[MAXN*30];
int root[MAXN],tot=0;//节点个数 
int last;//记录本次操作前线段树上的总结点数 
void build(int &k,int l,int r)
{
	k=++tot;
	if(l==r)
	{
		tr[k].fa=l,tr[k].dep=1;
		return ;
	}
	int mid=l+r>>1;
	build(tr[k].ch[0],l,mid),build(tr[k].ch[1],mid+1,r);
}
int find(int k,int l,int r,int x,int id)
{
	if(l==r)
	{
		if(tr[k].fa==l)//说明找到了k节点的祖先 
			return k;
		return find(root[id],1,n,tr[k].fa,id);
	}
	int mid=l+r>>1;
	if(x<=mid)
		return find(tr[k].ch[0],l,mid,x,id);
	else
		return find(tr[k].ch[1],mid+1,r,x,id);
}
void modefy(int &k,int q,int l,int r,int x,int f)
{
	k=++tot,tr[k]=tr[q];
	if(l==r)
	{
		tr[k].fa=f;
		return ;
	}
	int mid=l+r>>1;
	if(x<=mid)
		modefy(tr[k].ch[0],tr[q].ch[0],l,mid,x,f);
	else
		modefy(tr[k].ch[1],tr[q].ch[1],mid+1,r,x,f);
}
void merge(int &k,int q,int l,int r,int x)//按深度合并 
{
	if(k<=last)
		k=++tot,tr[k]=tr[q];
	if(l==r)
	{
		tr[k].dep++;
		return ;
	}
	int mid=l+r>>1;
	if(x<=mid)
		merge(tr[k].ch[0],tr[q].ch[0],l,mid,x);
	else
		merge(tr[k].ch[1],tr[q].ch[1],mid+1,r,x);
}
int main()
{
	n=read(),m=read();
	build(root[0],1,n);
	last=tot;
	for(int i=1;i<=m;i++)
	{
		int op=read(),x,y;
		if(op==1)
		{
			x=read(),y=read();
			root[i]=root[i-1];
			x=find(root[i],1,n,x,i),y=find(root[i],1,n,y,i);
			if(tr[x].fa==tr[y].fa)
				continue;
			if(tr[x].dep<tr[y].dep)
				swap(tr[x],tr[y]);
			modefy(root[i],root[i-1],1,n,tr[y].fa,tr[x].fa);//将y的子树合并到x上
			if(tr[x].dep==tr[y].dep)
				merge(root[i],root[i-1],1,n,tr[x].fa);
			last=tot;
		}
		if(op==2)
		{
			x=read();
			root[i]=root[x];
		}
		if(op==3)
		{
			x=read(),y=read();
			root[i]=root[i-1];
			x=find(root[i],1,n,x,i),y=find(root[i],1,n,y,i);
			if(tr[x].fa==tr[y].fa)
				printf("1\n");
			else
				printf("0\n");
		}
	}
	return 0;
}
2023/12/6 07:11
加载中...