左偏树模板求调,翻遍整个讨论区发现只有我28pts
查看原帖
左偏树模板求调,翻遍整个讨论区发现只有我28pts
526895
WYZ20030051楼主2023/7/7 19:47

不知道为啥,样例都没过...于是我抱着试一试的心态交了上去,得了28pts(这算骗分吗)

#include<iostream>
#include<cstdio>
#include<cmath>
#include<string>
#include<cstring>
#include<algorithm>
#include<cassert>
#include<stack>
#include<queue>
#include<vector>
#include<map>
#include<cstdlib>
using namespace std;
#define ll long long
#define ull unsigned long long
int read()
{
	int now=0,nev=1; 
	char c=getchar();
	while(c<'0' || c>'9') 
	{ 
		if(c=='-') 
			nev=-1; 
		c=getchar();
	}
	while(c>='0' && c<='9') 
	{ 
		now=(now<<1)+(now<<3)+(c&15); 
		c=getchar(); 
	}
	return now*nev;
}
const int MAXN=5e5+10;
int n,m;
int a[MAXN];
int ls[MAXN],rs[MAXN];
int fa[MAXN],dep[MAXN];
int find(int x)
{
	if(fa[x]==x)
		return x;
	return fa[x]=find(fa[x]);
}
int merge(int x,int y)
{
	if(!x || !y)
		return x^y;//返回不为空的树 
	if(a[x]>a[y])
		swap(x,y);//将值小的放左边 
	rs[x]=merge(rs[x],y);
	if(dep[ls[x]]<dep[rs[x]])//如果左边树高较小,则不满足左偏的性质,此时交换ls[x]和rs[x] 
		swap(ls[x],rs[x]);
	dep[x]=dep[rs[x]]+1;//合并后原树树高为右子树树高加一 
	return x;
}
void remove(int x)
{
	if(a[x]<0)
		return ;
	fa[ls[x]]=ls[x];
	fa[rs[x]]=rs[x];
	fa[x]=merge(ls[x],rs[x]);
	ls[x]=rs[x]=dep[x]=0;
	a[x]=-1;
}
int main()
{
	n=read(),m=read();
	for(int i=1;i<=n;i++)
	{
		a[i]=read();
		fa[i]=i;
		ls[i]=rs[i]=dep[i]=0;
	}
	dep[0]=a[0]=-1;
	for(int i=1;i<=m;i++)
	{
		int op;
		op=read();
		if(op==1)
		{
			int x,y;
			x=read(),y=read();
			if(a[x]<0 || a[y]<0)
				continue;
			x=find(x);
			y=find(y);
			if(x!=y)
				x=merge(x,y);
		}
		if(op==2)
		{
			int x;
			x=read();
			if(a[x]<0)
				printf("-1\n");
			else
			{
				x=find(x);
				printf("%d\n",a[x]);
				remove(x);
			}
		}
	}
	return 0;
}
2023/7/7 19:47
加载中...