您的位置:首页 > 其它

BZOJ2151 种树

2015-01-31 10:27 267 查看
做过数据备份的话,这题就是一样的了

记录下每一段的前一个位置和后一个位置,每次可以进行反悔操作即可。

/**************************************************************
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: