论避免手写堆的各种姿势(1)

测试题目:洛谷P3378 【模板】堆

插入,删除,取最小

 


 

方法0:STL 优先队列

1198ms

 

#include<iostream>
#include<cstdio>
#include<queue>
#include<vector> 
using namespace std;
inline int read(){
    char c=getchar();int x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();}
    return x*f;
}
int n,op;
priority_queue<int, vector<int>, greater<int> > q;
int main(){
    //freopen("in.txt","r",stdin);
    n=read();
    for(int i=1;i<=n;i++){
        op=read();
        if(op==1) q.push(read());
        else if(op==2) printf("%d\n",q.top());
        else q.pop();
    }
}
View Code

 


方法1:algorithm库 heap系列函数

520ms 这个数字.....

make_heap(begin,end,cmp) 建堆 前闭后开    cmp定义<运算,可选 注意同样是默认大根堆

push_heap(begin,end,cmp) 插入 前闭后开 插入最后一个元素

pop_heap(begin,end,cmp) 删除 把堆顶元素放到最后一个位置

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long ll;
const int N=1e6+5;
inline int read(){
    char c=getchar();int x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
int n,op,x;
int a[N],len=0;
inline bool cmp(int a,int b){return a>b;}
int main(){
    n=read();
    for(int i=1;i<=n;i++){
        op=read();
        if(op==1){
            a[++len]=read();
            push_heap(a+1,a+1+len,cmp);
        }else if(op==2) printf("%d\n",a[1]);
        else pop_heap(a+1,a+1+len,cmp),len--;
    }
}
View Code

方法2:pb_ds库 

据说竞赛可用

#include <ext/pb_ds/priority_queue.hpp>

using namespace __gnu_pbds; 

支持配对堆(pairing_heap)、二叉堆(binary_heap)、二项堆(binomial_heap)、冗余计数二项堆(redundant-counter binomial_heap,没找到通用译名,故自行翻译)、经改良的斐波那契堆(thin_heap)

使用方法:__gnu_pbds::priority_queue<int,greater<int>,pairing_heap_tag> q; 第三个参数换成想用的名称就行了,默认配对堆

支持join操作,然而本文不考虑

pairing_heap_tag 428ms

binomial_heap 544ms

rc_binomial_heap 610ms

thin_heap_tag 790ms

结合WC课件中的测试,用默认的pairing就好了

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <ext/pb_ds/priority_queue.hpp>
using namespace std;
using namespace __gnu_pbds; 
inline int read(){
    char c=getchar();int x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x*f;
}
int n,op,x;
__gnu_pbds::priority_queue<int,greater<int> > q;
int main(){
    n=read();
    for(int i=1;i<=n;i++){
        op=read();
        if(op==1) q.push(read());
        else if(op==2) printf("%d\n",q.top());
        else q.pop();
    }
}
View Code

 

posted @ 2017-01-10 16:46  Candy?  阅读(1266)  评论(1)    收藏  举报