即求连续k个数的中位数。。。

我们维护两个堆,一个大根堆一个小根堆:

小根堆维护的是区间前一半大的数,大根堆维护的是区间后一半小的数,且小根堆中的所有数都比大根堆内所有数大

这样子中位数就是大根堆的堆顶元素 or 小根堆的堆顶元素 or 他们的平均数(貌似并没有区别QAQ)

每次区间移动一位的时候,把其中的一个数删去再加入一个数,保证两个堆的大小不变

所以我们需要维护两个堆,支持插入,定点删除

于是我用了平板电视= =

 

  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 }
View Code

 

posted on 2015-04-05 14:04  Xs酱~  阅读(493)  评论(0编辑  收藏  举报