之前用N^2的方法勉强过了,900+ms
每次取出最小的两块板子,合并以后就推入堆,总共推N-1次,用时47ms, NlogN
/*
PROG: Fence Repair (heap)
LANG: C++11
*/
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <cstdlib>
#include <climits>
#include <ctype.h>
#include <queue>
#include <stack>
#include <vector>
#include <utility>
#include <deque>
#include <set>
#include <map>
#include <iostream>
#include <fstream>
#include <algorithm>
#include <time.h>
using namespace std;
#define mst(a,b) memset(a,b,sizeof(a))
typedef long long ll;
const int N = 100010;
const ll MOD = 1000000007;
const int INF = 0x7fffffff;
ll heap[N];
ll size = 0;
void push(ll x){
ll i = size++;
while(i > 0){
ll p = (i-1)/2;
if(heap[p] < x)
break;
else{
heap[i] = heap[p];
i = p;
}
}
heap[i] = x;
}
ll pop(){
ll ans = heap[0];
ll tmp = heap[size-1];
size--;
ll i = 0;
ll l, r;
while(i * 2 +1 < size){
l = 2 * i + 1;
r = 2 * i + 2;
if(r < size && heap[r] < heap[l])
l = r; // make a the smaller one
if (heap[l] > tmp)
break;
heap[i] = heap[l];
i = l;
}
heap[i] = tmp;
return ans;
}
int main()
{
int n, i;
ll sum = 0, tmp;
cin >> n;
for(i = 0; i < n; i++){
scanf("%lld", &tmp);
push(tmp);
}
ll a, b;
for(i = 0; i < n-1; i++){
a = pop();
b = pop();
tmp = a+b;
push(tmp);
sum += tmp;
}
cout << sum << endl;
return 0;
}