即求连续k个数的中位数。。。
我们维护两个堆,一个大根堆一个小根堆:
小根堆维护的是区间前一半大的数,大根堆维护的是区间后一半小的数,且小根堆中的所有数都比大根堆内所有数大
这样子中位数就是大根堆的堆顶元素 or 小根堆的堆顶元素 or 他们的平均数(貌似并没有区别QAQ)
每次区间移动一位的时候,把其中的一个数删去再加入一个数,保证两个堆的大小不变
所以我们需要维护两个堆,支持插入,定点删除
于是我用了平板电视= =
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 /************************************************************** 2 Problem: 1112 3 User: rausen 4 Language: C++ 5 Result: Accepted 6 Time:868 ms 7 Memory:5900 kb 8 ****************************************************************/ 9 10 #include <cstdio> 11 #include <ext/pb_ds/priority_queue.hpp> 12 13 using namespace std; 14 using namespace __gnu_pbds; 15 16 typedef long long ll; 17 const int N = 1e5 + 5; 18 const int int_inf = 1e9; 19 const ll ll_inf = (ll) 1e18; 20 21 struct data { 22 int v, w; 23 data() {} 24 data(int _v, int _w) : v(_v), w(_w) {} 25 26 inline bool operator < (const data &x) const { 27 return v < x.v; 28 } 29 inline bool operator > (const data &x) const { 30 return v > x.v; 31 } 32 }; 33 34 typedef __gnu_pbds :: priority_queue <data, less <data>, pairing_heap_tag> min_heap; 35 typedef __gnu_pbds :: priority_queue <data, greater <data>, pairing_heap_tag> max_heap; 36 37 min_heap mnh; 38 min_heap :: point_iterator mnhw[N]; 39 max_heap mxh; 40 max_heap :: point_iterator mxhw[N]; 41 ll tot_mxh, tot_mnh; 42 int n, k, k1; 43 int a[N]; 44 ll ans; 45 46 inline int read() { 47 static int x; 48 static char ch; 49 x = 0, ch = getchar(); 50 while (ch < '0' || '9' < ch) ch = getchar(); 51 while ('0' <= ch && ch <= '9') 52 x = x * 10 + ch - '0', ch = getchar(); 53 return x; 54 } 55 56 inline void insert_mx(int i) { 57 mxhw[i] = mxh.push(data(a[i], i)); 58 tot_mxh += a[i]; 59 } 60 61 inline void insert_mn(int i) { 62 mnhw[i] = mnh.push(data(a[i], i)); 63 tot_mnh += a[i]; 64 } 65 66 inline int pop_mx() { 67 static data tmp; 68 tmp = mxh.top(), mxh.pop(); 69 tot_mxh -= tmp.v, mxhw[tmp.w] = NULL; 70 return tmp.w; 71 } 72 73 inline int pop_mn() { 74 static data tmp; 75 tmp = mnh.top(), mnh.pop(); 76 tot_mnh -= tmp.v, mnhw[tmp.w] = NULL; 77 return tmp.w; 78 } 79 80 inline int delete_mx(int i) { 81 tot_mxh -= a[i]; 82 mxh.modify(mxhw[i], data(0, i)); 83 mxh.pop(), mxhw[i] = NULL; 84 } 85 86 inline int delete_mn(int i) { 87 tot_mnh -= a[i]; 88 mnh.modify(mnhw[i], data(int_inf, i)); 89 mnh.pop(), mnhw[i] = NULL; 90 } 91 92 #define mid mnh.top().v 93 inline ll calc_ans() { 94 return tot_mxh + 1ll * mid * (k - 2 * k1) - tot_mnh; 95 } 96 #undef mid 97 98 int main() { 99 int i, x, y; 100 n = read(), k = read(), k1 = k >> 1; 101 for (i = 1; i <= n; ++i) a[i] = read(); 102 for (i = 1; i <= k; ++i) 103 insert_mx(i); 104 while (mxh.size() > k1) 105 i = pop_mx(), insert_mn(i); 106 ans = ll_inf; 107 for (i = k + 1; i <= n + 1; ++i) { 108 ans = min(ans, calc_ans()); 109 if (i == n + 1) break; 110 if (mxhw[i - k] == NULL) delete_mn(i - k); 111 else delete_mx(i - k); 112 insert_mx(i); 113 while (mxh.size() && mnh.size() && mnh.top().v > mxh.top().v) { 114 x = pop_mx(), insert_mn(x); 115 x = pop_mn(), insert_mx(x); 116 } 117 while (mxh.size() > k1) 118 x = pop_mx(), insert_mn(x); 119 while (mxh.size() < k1) 120 x = pop_mn(), insert_mx(x); 121 } 122 printf("%lld\n", ans); 123 return 0; 124 }
By Xs酱~ 转载请说明
博客地址:http://www.cnblogs.com/rausen