P3377

【模板】左偏树(可并堆)

题目描述

如题,一开始有 \(n\) 个小根堆,每个堆包含且仅包含一个数。接下来需要支持两种操作:

  1. 1 x y:将第 \(x\) 个数和第 \(y\) 个数所在的小根堆合并(若第 \(x\) 或第 \(y\) 个数已经被删除或第 \(x\) 和第 \(y\) 个数在用一个堆内,则无视此操作)。

  2. 2 x:输出第 \(x\) 个数所在的堆最小数,并将这个最小数删除(若有多个最小数,优先删除先输入的;若第 \(x\) 个数已经被删除,则输出 \(-1\) 并无视删除操作)。

输入格式

第一行包含两个正整数 \(n, m\),分别表示一开始小根堆的个数和接下来操作的个数。

第二行包含 \(n\) 个正整数,其中第 \(i\) 个正整数表示第 \(i\) 个小根堆初始时包含且仅包含的数。

接下来 \(m\) 行每行 \(2\) 个或 \(3\) 个正整数,表示一条操作,格式如下:

操作 \(1\)1 x y

操作 \(2\)2 x

输出格式

输出包含若干行整数,分别依次对应每一个操作 \(2\) 所得的结果。

样例 #1

样例输入 #1

5 5
1 5 4 2 3
1 1 5
1 2 5
2 2
1 4 2
2 2

样例输出 #1

1
2

提示

【数据规模】

对于 \(30\%\) 的数据:\(n\le 10\)\(m\le 10\)
对于 \(70\%\) 的数据:\(n\le 10^3\)\(m\le 10^3\)
对于 \(100\%\) 的数据:\(n\le 10^5\)\(m\le 10^5\),初始时小根堆中的所有数都在 int 范围内。

并查集+pbds的优先队列
注意 less<did>需要自己定义operator <
bool operator < (const did& t)const{return v>t.v}
注意优先队列里的自定义operator比较奇怪好像是反着的
由于默认是最大堆,所以cmp(x,y)<=>y优先于x的条件,跟sort的刚好相反
相当于优先队列是t.~<~ 
其他的都是~<t.~
然后注意join操作是对fx fy 
del 存储的是x 和 y 不要打快了
还有一个点:
fx fy的uni和join方向要统一
fa[fx]=fy q[fy].join(q[fx])
点击查看代码
#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#include<ext/pb_ds/priority_queue.hpp>
using namespace std;
using namespace __gnu_pbds;
struct did{
	int v,id;
	did(int a,int b)
	{
		v=a,id=b;
	}
	bool operator<(did t)const
	{
		if(v==t.v)return id>t.id;
		return v>t.v;	
	} 
	
};
__gnu_pbds::priority_queue<did,less<did>,pairing_heap_tag>q[100005];
int n,m,x,y,fa[100005];
bool del[100005];
int getfa(int x)
{
	if(fa[x]==x)return x;
	return fa[x]=getfa(fa[x]);
}
int main()
{
	ios::sync_with_stdio(false);
	cin>>n>>m;
	for(int i=1;i<=n;i++){fa[i]=i;cin>>x;did z(x,i);q[i].push(z);}
	while(m--)
	{
		int op;
		cin>>op;
		if(op==1)
		{
			cin>>x>>y;
			int fx=getfa(x),fy=getfa(y);
			if(fx==fy)continue;
			if(del[x]||del[y])continue;
			fa[fy]=fx;
			q[fx].join(q[fy]);
		}
		else
		{
			cin>>x;
			int fx=getfa(x);
			if(del[x]||q[fx].empty())cout<<-1<<"\n";
			else
			{
				did z=q[fx].top();
				cout<<z.v<<"\n";
				q[fx].pop();
				del[z.id]=1;
//				fa[fx]=0;	
			}	
		}
	}
}
posted @ 2023-01-20 11:31  PKU_IMCOMING  阅读(15)  评论(0)    收藏  举报