AcWing 839. 模擬堆(模板)

題目鏈接:點擊這裏

在這裏插入圖片描述
在這裏插入圖片描述

帶映射關係的堆:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;
const int N = 100010;

int h[N], ph[N], hp[N], sz;
// h[N]存儲堆中的值, h[1]是堆頂,x的左兒子是2x, 右兒子是2x+1
// ph[k]存儲第k個插入的點在堆中的位置
// hp[k]存儲堆中下標是k的點是第幾個插入的


void heap_swap(int a, int b)
{
    swap(ph[hp[a]], ph[hp[b]]);
    swap(hp[a], hp[b]);
    swap(h[a], h[b]);
}

void down(int u)
{
    int t = u;
    if(u * 2 <= sz && h[u * 2] < h[t])  t = u * 2;
    if(u * 2 + 1 <= sz && h[u * 2 + 1] < h[t])  t = u * 2 + 1;
    if(u != t)
    {
        heap_swap(t, u);
        down(t);
    }
}

void up(int u)
{
    while(u / 2 && h[u] < h[u / 2])
    {
        heap_swap(u, u / 2);
        u >>= 1;
    }
}

int main()
{
    int n, m = 0;       //m表示當前是第幾個插入的數
    scanf("%d", &n);
    while(n--)
    {
        char op[5];
        int k, x;
        scanf("%s", op);
        
        if(!strcmp(op, "I"))
        {
            scanf("%d", &x);
            sz++;
            m++;
            ph[m] = sz;
            hp[sz] = m;
            h[sz] = x;
            up(sz);
        }
        else if(!strcmp(op, "PM"))
        {
            printf("%d\n", h[1]);
        }
        else if(!strcmp(op, "DM"))
        {
            heap_swap(1, sz);
            sz--;
            down(1);
        }
        else if(!strcmp(op, "D"))
        {
            scanf("%d", &k);
            k = ph[k];
            heap_swap(k, sz);
            sz--;
            down(k), up(k);
        }
        else if(!strcmp(op, "C"))
        {
            scanf("%d%d", &k, &x);
            k = ph[k];
            h[k] = x;
            down(k), up(k);
        }
    }
    
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章