BZOJ1112 [POI2008]砖块Klo
2015-04-05 14:04
225 查看
即求连续k个数的中位数。。。
我们维护两个堆,一个大根堆一个小根堆:
小根堆维护的是区间前一半大的数,大根堆维护的是区间后一半小的数,且小根堆中的所有数都比大根堆内所有数大
这样子中位数就是大根堆的堆顶元素 or 小根堆的堆顶元素 or 他们的平均数(貌似并没有区别QAQ)
每次区间移动一位的时候,把其中的一个数删去再加入一个数,保证两个堆的大小不变
所以我们需要维护两个堆,支持插入,定点删除
于是我用了平板电视= =
View Code
我们维护两个堆,一个大根堆一个小根堆:
小根堆维护的是区间前一半大的数,大根堆维护的是区间后一半小的数,且小根堆中的所有数都比大根堆内所有数大
这样子中位数就是大根堆的堆顶元素 or 小根堆的堆顶元素 or 他们的平均数(貌似并没有区别QAQ)
每次区间移动一位的时候,把其中的一个数删去再加入一个数,保证两个堆的大小不变
所以我们需要维护两个堆,支持插入,定点删除
于是我用了平板电视= =
/************************************************************** Problem: 1112 User: rausen Language: C++ Result: Accepted Time:868 ms Memory:5900 kb ****************************************************************/ #include <cstdio> #include <ext/pb_ds/priority_queue.hpp> using namespace std; using namespace __gnu_pbds; typedef long long ll; const int N = 1e5 + 5; const int int_inf = 1e9; const ll ll_inf = (ll) 1e18; struct data { int v, w; data() {} data(int _v, int _w) : v(_v), w(_w) {} inline bool operator < (const data &x) const { return v < x.v; } inline bool operator > (const data &x) const { return v > x.v; } }; typedef __gnu_pbds :: priority_queue <data, less <data>, pairing_heap_tag> min_heap; typedef __gnu_pbds :: priority_queue <data, greater <data>, pairing_heap_tag> max_heap; min_heap mnh; min_heap :: point_iterator mnhw ; max_heap mxh; max_heap :: point_iterator mxhw ; ll tot_mxh, tot_mnh; int n, k, k1; int a ; ll ans; inline int read() { static int x; static char ch; x = 0, ch = getchar(); while (ch < '0' || '9' < ch) ch = getchar(); while ('0' <= ch && ch <= '9') x = x * 10 + ch - '0', ch = getchar(); return x; } inline void insert_mx(int i) { mxhw[i] = mxh.push(data(a[i], i)); tot_mxh += a[i]; } inline void insert_mn(int i) { mnhw[i] = mnh.push(data(a[i], i)); tot_mnh += a[i]; } inline int pop_mx() { static data tmp; tmp = mxh.top(), mxh.pop(); tot_mxh -= tmp.v, mxhw[tmp.w] = NULL; return tmp.w; } inline int pop_mn() { static data tmp; tmp = mnh.top(), mnh.pop(); tot_mnh -= tmp.v, mnhw[tmp.w] = NULL; return tmp.w; } inline int delete_mx(int i) { tot_mxh -= a[i]; mxh.modify(mxhw[i], data(0, i)); mxh.pop(), mxhw[i] = NULL; } inline int delete_mn(int i) { tot_mnh -= a[i]; mnh.modify(mnhw[i], data(int_inf, i)); mnh.pop(), mnhw[i] = NULL; } #define mid mnh.top().v inline ll calc_ans() { return tot_mxh + 1ll * mid * (k - 2 * k1) - tot_mnh; } #undef mid int main() { int i, x, y; n = read(), k = read(), k1 = k >> 1; for (i = 1; i <= n; ++i) a[i] = read(); for (i = 1; i <= k; ++i) insert_mx(i); while (mxh.size() > k1) i = pop_mx(), insert_mn(i); ans = ll_inf; for (i = k + 1; i <= n + 1; ++i) { ans = min(ans, calc_ans()); if (i == n + 1) break; if (mxhw[i - k] == NULL) delete_mn(i - k); else delete_mx(i - k); insert_mx(i); while (mxh.size() && mnh.size() && mnh.top().v > mxh.top().v) { x = pop_mx(), insert_mn(x); x = pop_mn(), insert_mx(x); } while (mxh.size() > k1) x = pop_mx(), insert_mn(x); while (mxh.size() < k1) x = pop_mn(), insert_mx(x); } printf("%lld\n", ans); return 0; }
View Code
相关文章推荐
- 【BZOJ】1112 [POI2008]砖块Klo 平衡树
- bzoj1112 POI2008 砖块Klo 树状数组
- 【bzoj1112】[POI2008]砖块Klo
- bzoj1112 [POI2008]砖块Klo
- bzoj 1112 [POI2008]砖块Klo
- 【枚举】【权值分块】bzoj1112 [POI2008]砖块Klo
- bzoj 1112: [POI2008]砖块Klo treap
- Bzoj1112:[POI2008]砖块Klo:splay
- [bzoj1112][POI2008]砖块Klo
- bzoj1112 [POI2008]砖块Klo
- BZOJ 1112 [POI2008]砖块Klo Treap
- bzoj 1112: [POI2008]砖块Klo(splay)
- BZOJ 1112 [POI2008]砖块Klo(可持久化线段树)
- bzoj1112 [POI2008]砖块Klo(平衡树/map/树状数组)
- [主席树] BZOJ1112: [POI2008]砖块Klo
- 【POI2008】【BZOJ1112】砖块Klo
- [BZOJ 1112] [POI2008] 砖块Klo 【区间K大】
- BZOJ 1112 POI2008 砖块Klo Treap
- BZOJ 1112: [POI2008]砖块Klo 平衡树,思维,枚举
- BZOJ 1112: [POI2008]砖块Klo treap