Poj--3784(暴力 / 对顶堆优化)
2014-12-05 23:52:24
思路:动态维护中位数问题,一开始直接sort暴力水过,后来发现有一种用对顶堆来做的写法。具体可看:http://hi.baidu.com/xutdddhagomprsr/item/d85f5122a900018ab6326371
对顶堆:用一个大顶堆维护前半部分较小数,再用一个小顶堆维护后半部分较大数,同时要平衡两个堆的大小,那么中位数就在两个堆top中了。
1 /************************************************************************* 2 > File Name: 3784.cpp 3 > Author: Nature 4 > Mail: 564374850@qq.com 5 > Created Time: Fri 05 Dec 2014 10:59:49 PM CST 6 ************************************************************************/ 7 8 #include <cstdio> 9 #include <cstring> 10 #include <cstdlib> 11 #include <cmath> 12 #include <vector> 13 #include <map> 14 #include <set> 15 #include <stack> 16 #include <queue> 17 #include <iostream> 18 #include <algorithm> 19 using namespace std; 20 #define lp (p << 1) 21 #define rp (p << 1|1) 22 #define getmid(l,r) (l + (r - l) / 2) 23 #define MP(a,b) make_pair(a,b) 24 typedef long long ll; 25 const int INF = 1 << 30; 26 const int maxn = 10010; 27 28 int T,tag,N; 29 int ans[maxn],cnt; 30 31 struct Heap{ 32 int t[maxn << 2]; 33 int sz; 34 void clear(){ sz = 0;} 35 void Push(int val,int flag){ 36 int p = ++sz; 37 while(p > 1){ 38 int fa = p / 2; 39 if(flag == -1 && t[fa] <= val) break; 40 if(flag == 1 && t[fa] >= val) break; 41 t[p] = t[fa]; 42 p = fa; 43 } 44 t[p] = val; 45 } 46 int Pop(int flag){ 47 int root = t[1]; 48 int val = t[sz]; 49 int p = 1; 50 while(p * 2 <= sz){ 51 int a = p * 2,b = p * 2 + 1; 52 if(b <= sz){ 53 if(flag == -1 && t[b] < t[a]) a = b; 54 if(flag == 1 && t[b] > t[a]) a = b; 55 } 56 if(flag == -1 && t[a] >= val) break; 57 if(flag == 1 && t[a] <= val) break; 58 t[p] = t[a]; 59 p = a; 60 } 61 --sz; 62 t[p] = val; 63 return root; 64 } 65 }h1,h2; 66 67 int main(){ 68 int tmp; 69 scanf("%d",&T); 70 while(T--){ 71 scanf("%d%d",&tag,&N); 72 h1.clear(); 73 h2.clear(); 74 cnt = 0; 75 for(int i = 1; i <= N; ++i){ 76 scanf("%d",&tmp); 77 if(!h1.sz || tmp <= h1.t[1]) h1.Push(tmp,1); 78 else h2.Push(tmp,-1); 79 if(i % 2){ 80 while(h1.sz > h2.sz + 1){ 81 int val = h1.Pop(1); 82 h2.Push(val,-1); 83 } 84 while(h1.sz < h2.sz){ 85 int val = h2.Pop(-1); 86 h1.Push(val,1); 87 } 88 ans[++cnt] = h1.t[1]; 89 } 90 } 91 printf("%d %d\n",tag,cnt); 92 for(int i = 1; i <= cnt; ++i){ 93 printf("%d",ans[i]); 94 if(i != cnt){ 95 if(i % 10 == 0) printf("\n"); 96 else printf(" "); 97 } 98 } 99 printf("\n"); 100 } 101 return 0; 102 }