ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

[AcWing 839] 模拟堆

2022-05-03 18:04:38  阅读:150  来源: 互联网

标签:sz int hp 839 swap ph 节点 模拟 AcWing


image
image


点击查看代码
#include<iostream>

using namespace std;
const int N = 1e5 + 10;
int h[N], sz, m;
int ph[N], hp[N];
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 (2 * u <= sz && h[2 * u] < h[t]) t = 2 * u;
    if (2 * u + 1 <= sz && h[2 * u + 1] < h[t]) t = 2 * u + 1;
    if (t != u) {
        heap_swap(u, t);
        down(t);
    }
}
void up(int u)
{
    while (u / 2 && h[u / 2] > h[u]) {
        heap_swap(u / 2, u);
        u /= 2;
    }
}
int main()
{
    int n;
    cin >> n;
    while (n --) {
        string s;
        int k, x;
        cin >> s;
        if (s == "I") {
            cin >> x;
            sz ++;
            m ++;
            h[sz] = x;
            ph[m] = sz, hp[sz]= m;
            up(sz);
        }
        else if (s == "PM") cout << h[1] << endl;
        else if (s == "DM") {
            heap_swap(1, sz);
            sz --;
            down(1);
        }
        else if (s == "D") {
            cin >> k;
            k = ph[k];
            heap_swap(k, sz);
            sz --;
            down(k), up(k);
        }
        else if (s == "C") {
            cin >> k >> x;
            k = ph[k];
            h[k] = x;
            down(k), up(k);
        }
    }
    return 0;
}

  1. 维护小根堆的三个重要操作:
    ① heap_swap:当两个节点需要交换时,除了交换节点的值,还要把和编号之间的双向指针 hp 和 ph 交换(hp 表示堆节点指向编号节点, ph 表示编号节点指向堆节点);
    ② down:维护 u 节点及其以下的节点,当出现孩子节点的值小于父节点的值时,把这两个节点用 heap_swap 交换;
    ③ up:维护 u 节点及其以上的节点,当出现父节点的值大于孩子节点的值时,把两个节点用 hedp_swap 交换;(u 无论是左孩子还是右孩子,u / 2 都表示同一个父节点)
  2. 在进行删除第 k 个插入的数这个操作时,需要先让 k = ph[ k ],然后再用 swap 交换 k 和 sz 的值,如果直接用 swap 交换 ph[ k ] 和 sz 的值,那么交换后,ph[ k ] 指向的是 sz,无法用 down 和 up 处理原来 k 指向的那个位置;(head_swap 不会交换数组中的下标,用 k 保存 p[ k ] 后,k 就一直是处理的那个节点对应的数组下标)

标签:sz,int,hp,839,swap,ph,节点,模拟,AcWing
来源: https://www.cnblogs.com/wKingYu/p/16218872.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有