正题
题目链接:https://www.luogu.com.cn/problem/P3377
题目大意
开始时 个只有一个数的集合,要求支持
- 合并两个集合
- 查询一个集合中的最小值并删除
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1e5+10;
int n,m,val[N];
struct Left_tree{
int dis[N],fa[N],t[N][2];
int Merge(int x,int y)
{
if(!x||!y) return x+y;
if(val[x]>val[y]||(val[x]==val[y]&&x>y))
swap(x,y);
int &ls=t[x][0],&rs=t[x][1];
rs=Merge(rs,y);
if(dis[ls]<dis[rs]) swap(ls,rs);
fa[rs]=fa[ls]=x;
dis[x]=dis[rs]+1;
return x;
}
void Del(int x){
int ls=t[x][0],rs=t[x][1];
fa[ls]=ls;fa[rs]=rs;val[x]=-1;
fa[x]=Merge(ls,rs);
}
int Get(int x)
{return (fa[x]==x)?(x):(fa[x]=Get(fa[x]));}
}T;
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&val[i]),T.fa[i]=i;
while(m--){
int op,x,y;
scanf("%d%d",&op,&x);
if(op==1){
scanf("%d",&y);
if(val[x]==-1||val[y]==-1)
continue;
x=T.Get(x);y=T.Get(y);
T.Merge(x,y);
}
if(op==2){
if(val[x]==-1){printf("-1\n");continue;}
x=T.Get(x);printf("%d\n",val[x]);T.Del(x);
}
}
}