BZOJ2151 种树
2015-01-31 10:27
267 查看
做过数据备份的话,这题就是一样的了
记录下每一段的前一个位置和后一个位置,每次可以进行反悔操作即可。
View Code
记录下每一段的前一个位置和后一个位置,每次可以进行反悔操作即可。
/************************************************************** Problem: 2151 User: rausen Language: C++ Result: Accepted Time:440 ms Memory:6424 kb ****************************************************************/ #include <cstdio> #include <queue> using namespace std; const int N = 200005; struct data { int w, v; data() {} data(int _w, int _v) : w(_w), v(_v) {} inline bool operator < (const data &x) const { return v == x.v ? w < x.w : v < x.v; } }; int n, m, ans; int a , pre , nxt ; bool vis ; priority_queue <data> h; int read() { int x = 0, sgn = 1; char ch = getchar(); while (ch < '0' || '9' < ch) { if (ch == '-') sgn = -1; ch = getchar(); } while ('0' <= ch && ch <= '9') (x *= 10) += ch - '0', ch = getchar(); return x * sgn; } inline void del(int t) { int l = pre[t], r = nxt[t]; pre[t] = nxt[t] = 0, vis[t] = 1; pre[r] = l, nxt[l] = r; } inline void get_ans() { int t; while (vis[h.top().w]) h.pop(); ans += a[t = h.top().w]; h.pop(); a[t] = a[pre[t]] + a[nxt[t]] - a[t]; del(pre[t]), del(nxt[t]); h.push(data(t, a[t])); } int main() { int i; n = read(), m = read(); if (m > n / 2) { puts("Error!"); return 0; } for (i = 1; i <= n; ++i) { a[i] = read(); pre[i] = i - 1, nxt[i] = i + 1; h.push(data(i, a[i])); } pre[1] = n, nxt = 1; while (m--) get_ans(); printf("%d\n", ans); return 0; }
View Code
相关文章推荐
- bzoj 2151: 种树(贪心+堆+链表)
- BZOJ 2151 种树 贪心+优先队列+HASH
- bzoj 2151: 种树【贪心+堆】
- bzoj 2151: 种树 贪心+优先队列
- [BZOJ2151]种树(贪心+堆)
- [BZOJ2151] 种树 贪心
- BZOJ 2151 种树
- bzoj 2151 种树
- BZOJ 2151 种树
- 【国家集训队2011】【BZOJ2151】种树
- bzoj2151 种树
- 【bzoj2151】种树
- 2151: 种树 - BZOJ
- BZOJ 2151 种树(循环链表)
- 【BZOJ2151】种树,贪心+Splay乱搞
- bzoj-2151 种树
- BZOJ2151 种树 贪心+双向链表+优先队列
- 【BZOJ 2151】 种树|堆|贪心|链表
- [bzoj 2151]种树(贪心)
- BZOJ2151 种树