AcWing 839. 模拟堆

本文详细介绍了一种基于堆的数据结构实现,支持插入、查询最小值、删除最小值、删除指定下标的元素以及修改特定元素的值等操作。通过实例演示了如何在一系列操作中维护堆的性质,同时保持高效的数据检索和更新。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

知识点:建堆 + 扩展

维护一个集合,初始时集合为空,支持如下几种操作:

  1. “I x”,插入一个数x;
  2. “PM”,输出当前集合中的最小值;
  3. “DM”,删除当前集合中的最小值(数据保证此时的最小值唯一);
  4. “D k”,删除第k个插入的数;
  5. “C k x”,修改第k个插入的数,将其变为x;

现在要进行N次操作,对于所有第2个操作,输出当前集合的最小值。

输入格式

第一行包含整数N。

接下来N行,每行包含一个操作指令,操作指令为”I x”,”PM”,”DM”,”D k”或”C k x”中的一种。

输出格式

对于每个输出指令“PM”,输出一个结果,表示当前集合中的最小值。

每个结果占一行。

数据范围

1≤N≤1051≤N≤105
−109≤x≤109−109≤x≤109
数据保证合法。

输入样例:

8
I -10
PM
I -10
D 1
C 2 8
I 6
PM
DM

输出样例:

-10
6
//建堆
//删除最小值
//删除指定下标k
//插入
//修改k的值

import java.io.*;
import java.lang.Integer;

class Main{
    static int N = 100010;
    static int[] t = new int[N];//堆
    static int[] ph = new int[N];//指针到堆
    static int[] hp = new int[N];//堆到指针
    static int size = 0;
    public static void swap(int a ,int b){
        int temp=t[a];
        t[a] = t[b];
        t[b] = temp;
        
        temp = ph[hp[a]];
        ph[hp[a]] = ph[hp[b]];
        ph[hp[b]] = temp;
        
        temp = hp[a];
        hp[a] = hp[b];
        hp[b] = temp;
        
    }
    
    static void down(int n){//向下更新
        int x = n;
        if(n * 2 <= size && t[x] > t[n * 2])x = n * 2;
        if(n * 2 + 1 <= size && t[x] > t[n * 2 + 1])x = n * 2 + 1;
        if(n != x){
            swap(n, x);
            down(x);
        }
    }
    
    static void up(int n){//向上更新
        while(n / 2 != 0 && t[n / 2] > t[n]){
            swap(n / 2, n);
            n /= 2;
        }
    }
    
    
    public static void main(String[] args)throws Exception{
        
        BufferedReader buf = new BufferedReader(new InputStreamReader(System.in));
        BufferedWriter buw = new BufferedWriter(new OutputStreamWriter(System.out));
        int n = Integer.valueOf(buf.readLine());
        size = 0;
        int c = 0;
        for(int i = 1; i <= n; ++i){
           String[] params = buf.readLine().split(" ");
           if("I".equals(params[0])){
               c++;
               size++;
               t[size] = Integer.valueOf(params[1]);
               ph[c] = size;
               hp[size] = c;
               up(size);
           }else if("PM".equals(params[0])){
               buw.write(t[1] + "\n");
           }else if("DM".equals(params[0])){
               swap(1, size);
               size--;
               down(1);
           }else if("D".equals(params[0])){
               int k = Integer.valueOf(params[1]);
               k = ph[k];
               swap(k, size);
               size--;
               down(k);
               up(k);
           }else{
               int k = Integer.valueOf(params[1]);
               int v = Integer.valueOf(params[2]);
               t[ph[k]] = v;
               down(ph[k]);
               up(ph[k]);
           }
        }
        buw.flush();
        buf.close();
        buw.close();
        
    }
}


 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值