首页 > 代码库 > vijos1097 合并果子

vijos1097 合并果子

  手写了一发二叉堆。

#include<cstdio>
#include<cctype>
#include<algorithm>
using namespace std;
inline int read(){
    char c; while(c=getchar(),!isdigit(c)); int x=c-0;
    while(c=getchar(),isdigit(c)) x=x*10+c-0; return x;
}
int cnt,h[10001];
void up(int x){
    if(x==0 || x==1) return;
    if(h[x]<h[x/2]) swap(h[x/2],h[x]),up(x/2);
}
void down(int x){
    if(x*2>cnt) return;
    int to=0;
    if(x*2<cnt && h[x*2+1]<h[x*2]) to=1;
    if(h[x]>h[x*2+to]) swap(h[x],h[x*2+to]),down(x*2+to);
}
void push(int x){
    h[++cnt]=x;
    up(cnt);
}
void pop(){
    h[1]=h[cnt--];
    down(1);
}
int top(){return h[1];}
int main(){
    int n=read(),tot=0;
    cnt=n;
    for(int i=1;i<=n;i+=1) h[i]=read();
    for(int i=n;i>=1;i-=1) down(i);
    for(int i=1;i<n;i+=1){
        int x=top(); pop();
        x+=top(); pop();
        tot+=x; push(x);
    }
    printf("%d",tot);
    return 0;
}

 

vijos1097 合并果子