做过数据备份的话,这题就是一样的了
记录下每一段的前一个位置和后一个位置,每次可以进行反悔操作即可。
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 }