• BZOJ1112 [POI2008]砖块Klo


    即求连续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
    ", ans);
    123     return 0;
    124 }
    View Code
    By Xs酱~ 转载请说明 博客地址:http://www.cnblogs.com/rausen
  • 相关阅读:
    Openresty+redis实现灰度发布
    Nginx keepalived
    Nginx反向代理、负载均衡、动静分离、缓存、压缩、防盗链、跨域访问
    MYCAT扩容
    MYCAT全局序列
    MYCAT分库分表
    MySQL主从复制
    [redis] linux下集群篇(4) docker部署
    [nginx] CORS配置多域名
    [mysql] 归档工具pt-archiver,binlog格式由mixed变成row
  • 原文地址:https://www.cnblogs.com/rausen/p/4394062.html
Copyright © 2020-2023  润新知