http://www.lydsy.com/JudgeOnline/problem.php?id=1500
php
Time Limit: 10 Sec Memory Limit: 64 MB
Submit: 15301 Solved: 5063node
輸入的第1 行包含兩個數N 和M(M ≤20 000),N 表示初始時數列中數的個數,M表示要進行的操做數目。
第2行包含N個數字,描述初始時的數列。
如下M行,每行一條命令,格式參見問題描述中的表格。
任什麼時候刻數列中最多含有500 000個數,數列中任何一個數字均在[-1 000, 1 000]內。
插入的數字總數不超過4 000 000個,輸入文件大小不超過20MBytes。ui
對於輸入數據中的GET-SUM和MAX-SUM操做,向輸出文件依次打印結果,每一個答案(數字)佔一行。spa
9 8
2 -6 3 5 1 -5 -3 6 3
GET-SUM 5 4
MAX-SUM
INSERT 8 3 -5 7 2
DELETE 12 1
MAKE-SAME 3 3 2
REVERSE 3 6
GET-SUM 5 4
MAX-SUMcode
-1
10
1
10ip
#include <cstdio> #include <cstring> #include <algorithm> #include <queue> #include <vector> #include <ctime> #include <cstdlib> #define pii pair<int, int> #define mp make_pair #define ls C[rt][0] #define rs C[rt][1] using namespace std; template <typename ty> void read(ty &x) { x = 0; int f = 1; char ch = getchar(); while (ch > '9' || ch < '0') { if (ch == '-') f = -1; ch = getchar(); } while (ch >= '0' && ch <= '9') { x = x*10 + ch - '0'; ch = getchar(); } x *= f; } template <typename ty> ty Max(ty a, ty b) { return a > b ? a : b; } template <typename ty> ty Min(ty a, ty b) { return a < b ? a : b; } template <typename ty> int Chkmin(ty a, ty b) { return a > b ? a = b, 1 : 0; } template <typename ty> int Chkmax(ty a, ty b) { return a < b ? a = b, 1 : 0; } typedef long long LL; typedef double db; const int inf = 0x7fffffff; const int N = 5e5 + 160; int V[N], C[N][2], S[N], STK[N], KEY[N]; int TAG[N], REV[N], A[N], Q[4000016]; int LM[N], RM[N], TM[N], T[N]; int root, n, m, sz, tot; int pos, t, c; char OP[160]; void pushtag(int rt, int val) { if (!rt) return; V[rt] = val; T[rt] = S[rt] * val; LM[rt] = RM[rt] = TM[rt] = Max(val, val * S[rt]); TAG[rt] = 1; } void pushrev(int rt) { if (!rt) return; swap(C[rt][0], C[rt][1]); swap(LM[rt], RM[rt]); REV[rt] ^= 1; } void pushup(int rt) { if (!rt) return; S[rt] = S[ls] + S[rs] + 1; T[rt] = T[ls] + T[rs] + V[rt]; LM[rt] = Max(LM[ls], T[ls] + V[rt] + Max(LM[rs], 0)); RM[rt] = Max(RM[rs], T[rs] + V[rt] + Max(RM[ls], 0)); TM[rt] = Max(TM[ls], Max(TM[rs], V[rt] + Max(LM[rs], 0) + Max(RM[ls], 0))); } void pushdown(int rt) { if (!rt) return; if (TAG[rt]) { pushtag(ls, V[rt]); pushtag(rs, V[rt]); TAG[rt] = REV[rt] = 0; } if (REV[rt]) { pushrev(ls); pushrev(rs); REV[rt] = 0; } } int new_node() { int a, b; read(a); if (tot) b = Q[tot--]; else b = ++sz; V[b] = a; KEY[b] = rand(); C[b][0] = C[b][1] = 0; S[b] = 1; TAG[b] = REV[b] = 0; LM[b] = RM[b] = TM[b] = T[b] = a; return b; } int build(int s) { int lst = 0, top = 0; for (int i = 1; i <= s; ++ i) { int tmp = new_node(); lst = 0; while (top && KEY[tmp] < KEY[STK[top]]) { pushup(STK[top]); lst = STK[top]; STK[top--] = 0; } if (lst) C[tmp][0] = lst; if (top) C[STK[top]][1] = tmp; STK[++top] = tmp; } while (top) pushup(STK[top--]); return STK[1]; } pii split(int rt, int k) { if (!rt) return mp(0, 0); pii tmp; pushdown(rt); if (k > S[C[rt][0]]) { tmp = split(C[rt][1], k - S[C[rt][0]] - 1); C[rt][1] = tmp.first; pushup(rt); tmp.first = rt; } else { tmp = split(C[rt][0], k); C[rt][0] = tmp.second; pushup(rt); tmp.second = rt; } return tmp; } int merge(int ra, int rb) { if (!ra) return rb; if (!rb) return ra; pushdown(ra); pushdown(rb); if (KEY[ra] < KEY[rb]) { C[ra][1] = merge(C[ra][1], rb); pushup(ra); return ra; } else { C[rb][0] = merge(ra, C[rb][0]); pushup(rb); return rb; } } void recycle(int rt) { if (!rt) return; Q[++tot] = rt; recycle(C[rt][0]); recycle(C[rt][1]); } void work1() { read(pos); read(t); pii a = split(root, pos); root = merge(a.first, merge(build(t), a.second)); } void work2() { read(pos); read(t); pii a = split(root, pos - 1); pii b = split(a.second, t); recycle(b.first); root = merge(a.first, b.second); } void work3() { read(pos); read(t); read(c); if (!t) return; pii a = split(root, pos - 1); pii b = split(a.second, t); pushtag(b.first, c); root = merge(a.first, merge(b.first, b.second)); } void work4() { read(pos); read(t); if (!t) return; pii a = split(root, pos - 1); pii b = split(a.second, t); pushrev(b.first); root = merge(a.first, merge(b.first, b.second)); } void work5() { read(pos); read(t); if (!t) { printf("0\n"); return; } pii a = split(root, pos - 1); pii b = split(a.second, t); printf("%d\n", T[b.first]); root = merge(a.first, merge(b.first, b.second)); } void work6() { printf("%d\n", TM[root]); } int main () { read(n); read(m); LM[0] = RM[0] = TM[0] = V[0] = -inf; root = build(n); for (int i = 1; i <= m; ++ i) { scanf("%s", OP); if (OP[0] == 'I') work1(); if (OP[0] == 'D') work2(); if (OP[2] == 'K') work3(); if (OP[0] == 'R') work4(); if (OP[0] == 'G') work5(); if (OP[2] == 'X') work6(); } return 0; }