839. 模拟堆

模拟一个小根堆,最重要的部分是heap_swap部分
heap_node和node_heap分别维护堆中的第a个元素是第几个插入的元素,和第k个插入的元素在堆中的位置

#include<iostream>
using namespace std;

const int N = 100010;

int heap[N], ss;
int heap_node[N], node_heap[N];
int n, cnt;

void heap_swap(int a, int b){
    swap(heap[a], heap[b]);
    //注意下面两句话的先后位置,其实先后位置无所谓,但是这样写容易理解
    swap(node_heap[heap_node[a]], node_heap[heap_node[b]]);
    swap(heap_node[a], heap_node[b]);
}

void up(int x){
    while(x / 2 && heap[x / 2] > heap[x]){
        heap_swap(x / 2, x);
        x /= 2;
    }
}

void down(int x){
    int t = x;
    if(x * 2 <= ss && heap[x * 2] < heap[t]) t = x * 2;
    if(x * 2 + 1 <= ss && heap[x * 2 + 1] < heap[t]) t = x * 2 + 1;
    
    if(t != x){
        heap_swap(t, x);
        down(t);
    }
}


int main(){
    scanf("%d", &n);
    
    while(n --){
        char op[3];
        scanf("%s", op);
        
        if(op[0] == 'I'){
            ++ ss;
            ++ cnt;
            heap_node[ss] = cnt;
            node_heap[cnt] = ss;
            int x;
            scanf("%d", &x);
            heap[ss] = x;
            up(ss);
        }else if(op[0] == 'P')
            printf("%d\n", heap[1]);
        else if(op[0] == 'D'){
            if(op[1] == 'M'){
                heap_swap(1, ss --);
                down(1);
            }else{
                int k;
                scanf("%d", &k);
                int t = node_heap[k];
                heap_swap(t, ss --);
                down(t);
                up(t);
            }
        }else{
            int k, x;
            scanf("%d%d", &k, &x);
            int t = node_heap[k];
            heap[t] = x;
            down(t);
            up(t);
        }
    }
}
posted @ 2020-08-31 15:47  yys_c  阅读(173)  评论(0编辑  收藏  举报