1. 程式人生 > 其它 >P3378 【模板】堆

P3378 【模板】堆

P3378 【模板】堆

題目簡述

給定三個操作,求數列中最小的數,刪除數列中最小的數,插入一個新的數


思路

板子題沒什麼好說,用 stl 自帶的優先佇列很好寫,但手寫的也要掌握。
建議參考這篇部落格


程式碼

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+6;
int tr[N];
int main(){
  int n,len=0;
  cin>>n;
  while(n--){
    int op;
    cin>>op;
    switch(op){
      case 1:{
        int x;
        cin>>x;
        tr[++len]=x;
        int kdl=len;
        while(kdl){
          if(tr[kdl>>1]>tr[kdl])tr[kdl>>1]^=tr[kdl]^=tr[kdl>>1]^=tr[kdl];
          else break;
          kdl>>=1;
        }
        break;
      }
      case 2:{
        cout<<tr[1]<<endl;
        break;
      }
      case 3:{
        int kdl=1;
        tr[len]^=tr[1]^=tr[len]^=tr[1];
        tr[len]=0;
        len--;
        while(kdl<len){
          int ls=(kdl<<1),rs=(kdl<<1|1);
          if(ls>len){
            break;
          }
          if(rs>len){
            if(tr[ls]<tr[kdl])tr[kdl]^=tr[ls]^=tr[kdl]^=tr[ls];
            break;
          }
          if(tr[ls]<tr[rs]){
            if(tr[ls]<tr[kdl])tr[kdl]^=tr[ls]^=tr[kdl]^=tr[ls],kdl=ls;
            else break;
          }
          else {
            if(tr[rs]<tr[kdl])tr[kdl]^=tr[rs]^=tr[kdl]^=tr[rs],kdl=rs;
            else break;
          }
        }
        break;
      }
    }
  }
  return 0;
}

PS:有時候真的很奇怪我是怎麼能把程式碼都寫這麼冗長的/kk