用堆来实现优先队列:就本题来说即:1.建立最小堆
2.取堆顶元素a,更新最小堆
3.取堆顶元素b,更新最小堆
4.将c = a+b 插入最小堆,更新最小堆,并累加c(为所求)
5.重复步骤1,直到堆顶元素等于输入数据的和,即堆里仅有一个元素。
注意:最后累加c所用的数据类型为long long型。
1 #include<stdio.h> 2 #include<string.h> 3 #define INF 0x7fffffff 4 5 int n, D, sum, tree[(20000<<3)+1000], a[(20000<<1)+1000]; 6 7 void update(int cur) 8 { 9 for(int i = cur; i^1; i >>= 1) 10 tree[i>>1] = (a[tree[i]]>a[tree[i^1]] ? tree[i^1] : tree[i]); 11 } 12 13 void solve() 14 { 15 int b, c, d; 16 long long ans = 0; 17 int h = n; 18 while(a[tree[1]] < sum) 19 { 20 b = a[tree[1]]; 21 a[tree[1]] = INF; 22 update(D+tree[1]); 23 c = a[tree[1]]; 24 a[tree[1]] = INF; 25 update(D+tree[1]); 26 d = b + c; 27 ans += d; 28 a[++h] = d; 29 update(D+h); 30 } 31 printf("%lld\n",ans); 32 } 33 34 void init() 35 { 36 while(~scanf("%d",&n)) 37 { 38 sum = 0; 39 memset(a, 0x3c, sizeof(a)); 40 for(int i = 1; i <= n; i ++) 41 { 42 scanf("%d",&a[i]); 43 sum += a[i]; 44 } 45 for(D = 1; D < 2*n+2; D <<= 1); 46 for(int i = 0; i <= 2*n+2; i ++) 47 tree[D+i] = i; 48 for(int i = D-1; i > 0; i --) 49 tree[i] = (a[tree[i<<1]]>a[tree[i<<1|1]]?tree[i<<1|1]:tree[i<<1]); 50 solve(); 51 } 52 } 53 54 int main() 55 { 56 init(); 57 return 0; 58 }