BZOJ2151 种树

做过数据备份的话,这题就是一样的了

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

 1 /**************************************************************
 2     Problem: 2151
 3     User: rausen
 4     Language: C++
 5     Result: Accepted
 6     Time:440 ms
 7     Memory:6424 kb
 8 ****************************************************************/
 9  
10 #include <cstdio>
11 #include <queue>
12  
13 using namespace std;
14 const int N = 200005;
15  
16 struct data {
17   int w, v;
18   data() {}
19   data(int _w, int _v) : w(_w), v(_v) {}
20  
21   inline bool operator < (const data &x) const {
22     return v == x.v ? w < x.w : v < x.v;
23   }
24 };
25  
26 int n, m, ans;
27 int a[N], pre[N], nxt[N];
28 bool vis[N];
29 priority_queue <data> h;
30  
31 int read() {
32   int x = 0, sgn = 1;
33   char ch = getchar();
34   while (ch < '0' || '9' < ch) {
35     if (ch == '-') sgn = -1;
36     ch = getchar();
37   }
38   while ('0' <= ch && ch <= '9')
39     (x *= 10) += ch - '0', ch = getchar();
40   return x * sgn;
41 }
42  
43 inline void del(int t) {
44   int l = pre[t], r = nxt[t];
45   pre[t] = nxt[t] = 0, vis[t] = 1;
46   pre[r] = l, nxt[l] = r;
47 }
48  
49 inline void get_ans() {
50   int t;
51   while (vis[h.top().w]) h.pop();
52   ans += a[t = h.top().w];
53   h.pop();
54   a[t] = a[pre[t]] + a[nxt[t]] - a[t];
55   del(pre[t]), del(nxt[t]);
56   h.push(data(t, a[t]));
57 }
58  
59 int main() {
60   int i;
61   n = read(), m = read();
62   if (m > n / 2) {
63     puts("Error!");
64     return 0;
65   }
66   for (i = 1; i <= n; ++i) {
67     a[i] = read();
68     pre[i] = i - 1, nxt[i] = i + 1;
69     h.push(data(i, a[i]));
70   }
71   pre[1] = n, nxt[n] = 1;
72   while (m--)
73     get_ans();
74   printf("%d
", ans);
75   return 0;
76 }
View Code
By Xs酱~ 转载请说明 博客地址:http://www.cnblogs.com/rausen
原文地址:https://www.cnblogs.com/rausen/p/4263697.html