题解:P11266 【模板】完全体·堆
我们初始在序列每个位置建立一个堆。
考虑到本题需要对特定下标的元素进行修改,不妨在堆中存储二元组
本题操作中涉及堆的合并,考虑使用启发式合并处理:用
综上,得出四种操作的处理方法:
1 x:输出
2 x y:如果
3 x y z:删除
0 x y:删除
最后附上参考程序:
#include<bits/stdc++.h>
#define ll long long
#define PII pair<ll,int>
using namespace std;
set<PII> op[1000007];
int dy[1000007];
int wz[1000007];
int n,m,opt,l,r,c;
int dr;
set<PII>::iterator it;
PII tmp;
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
dy[i]=i;
scanf("%d",&dr);
wz[i]=dr;
op[i].insert(make_pair(dr,i));
}
while(m--){
scanf("%d%d",&opt,&l);
if(opt==1){
it=op[dy[l]].begin();
printf("%lld\n",(it->first));
}
else if(opt==2){
scanf("%d",&r);
if(op[dy[l]].size()<op[dy[r]].size()){
swap(dy[l],dy[r]);
}
for(it=op[dy[r]].begin();it!=op[dy[r]].end();it++){
op[dy[l]].insert(make_pair(it->first,it->second));
}
op[dy[r]].clear();
}
else if(opt==3){
scanf("%d%d",&r,&c);
tmp=make_pair(wz[r],r);
op[dy[l]].erase(tmp);
wz[r]=c;
op[dy[l]].insert(make_pair(c,r));
}
else{
scanf("%d",&r);
tmp=make_pair(wz[r],r);
op[dy[l]].erase(tmp);
}
}
return 0;
}