交换堆中的元素需要维护三个数组hp、ph、heap
#include<iostream>
#include<algorithm>
#include<math.h>
using namespace std;
const int N=1e5+10;
int ph[N],hp[N],heap[N];//从1开始存,heap[] 小顶堆
//ph[k]存储第k个插入的数的下标
//hp[i]存储的是堆里第i个点是第几个插入的 。互为逆函数
int num;
void swap_heap(int pos1,int pos2)
{
/*
int k1=hp[pos1],k2=hp[pos2];
swap(hp[pos1],hp[pos2]);
swap(ph[k1],ph[k2]);
swap(heap[pos1],heap[pos2]);
*/
swap(ph[hp[pos1]],ph[hp[pos2]]);
swap(hp[pos1],hp[pos2]);
swap(heap[pos1],heap[pos2]);
}
void up(int pos)
{
while( pos / 2 && heap[pos] < heap[pos/2])
{
swap_heap(pos,pos/2);
pos=pos/2;
}
}
void down(int pos)
{
int tem=pos;
if(pos * 2 <= num && heap[pos * 2] < heap[pos]) tem = pos * 2;
if((pos * 2 + 1) <= num && heap[pos * 2 + 1] < heap[tem]) tem=pos * 2 + 1;
if(tem != pos)
{
swap_heap(pos,tem);
down(tem);
}
}
int main()
{
int n,m;//m表示当前插入的第几个数
cin>>n;
num=0;m=0;
/*
I x,插入一个数 x
PM,输出当前集合中的最小值;
DM,删除当前集合中的最小值(数据保证此时的最小值唯一);
D k,删除第 k个插入的数;
C k x,修改第 k个插入的数,将其变为 x
*/
for(int i = 0;i < n; i++)
{
char op;
cin>>op;
if(op=='I')
{
int x;
cin>>x;
num++;m++;
ph[m]=num;hp[num]=m;
heap[num]=x;
up(num);
}
else if(op=='P')
{
getchar();
cout<<heap[1]<<endl;
}
else if(op=='D')
{
char op2;
op2=getchar();
if(op2=='M')
{
swap_heap(1,num);
num--;
down(1);
}
else
{
int k;
cin>>k;
int pos=ph[k];
swap_heap(pos,num);
num--;
up(pos);
down(pos);
}
}
else if(op=='C')
{
int k,x;
cin>>k>>x;
int pos=ph[k];
heap[pos]=x;
up(pos);down(pos);
}
}
return 0;
}