维护数列
请写一个程序,要求维护一个数列,支持以下 66 种操作:(请注意,格式栏 中的下划线 _
表示实际输入文件中的空格)
输入格式
第 11 行包含两个数 NN 和 MM,NN 表示初始时数列中数的个数,MM 表示要进行的操作数目。
第 22 行包含 NN 个数字,描述初始时的数列。
以下 MM 行,每行一条命令,格式参见问题描述中的表格。
输出格式
对于输入数据中的 GET-SUM
和 MAX-SUM
操作,向输出文件依次打印结果,每个答案(数字)占一行。
数据范围与约定
你可以认为在任何时刻,数列中至少有 11 个数。
输入数据一定是正确的,即指定位置的数在数列中一定存在。
50%50% 的数据中,任何时刻数列中最多含有 3000030000 个数;100%100% 的数据中,任何时刻数列中最多含有 500000500000 个数。
100%100% 的数据中,任何时刻数列中任何一个数字均在 [−1000,1000][−1000,1000] 内。
100%100% 的数据中,M≤20000M≤20000,插入的数字总数不超过 40000004000000 个,输入文件大小不超过 20 MBytes20 MBytes。
输入样例:
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-SUM
输出样例:
-1
10
1
10
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int N = 500010, INF = 1e9; int n, m; struct Node { int s[2], p, v; int rev, same; int size, sum, ms, ls, rs; void init(int _v, int _p) { s[0] = s[1] = 0, p = _p, v = _v; rev = same = 0; size = 1, sum = ms = v; ls = rs = max(v, 0); } }tr[N]; int root, nodes[N], tt; int w[N]; void pushup(int x) { auto &u = tr[x], &l = tr[u.s[0]], &r = tr[u.s[1]]; u.size = l.size + r.size + 1; u.sum = l.sum + r.sum + u.v; u.ls = max(l.ls, l.sum + u.v + r.ls); u.rs = max(r.rs, r.sum + u.v + l.rs); u.ms = max(max(l.ms, r.ms), l.rs + u.v + r.ls); } void pushdown(int x) { auto &u = tr[x], &l = tr[u.s[0]], &r = tr[u.s[1]]; if (u.same) { u.same = u.rev = 0; if (u.s[0]) l.same = 1, l.v = u.v, l.sum = l.v * l.size; if (u.s[1]) r.same = 1, r.v = u.v, r.sum = r.v * r.size; if (u.v > 0) { if (u.s[0]) l.ms = l.ls = l.rs = l.sum; if (u.s[1]) r.ms = r.ls = r.rs = r.sum; } else { if (u.s[0]) l.ms = l.v, l.ls = l.rs = 0; if (u.s[1]) r.ms = r.v, r.ls = r.rs = 0; } } else if (u.rev) { u.rev = 0, l.rev ^= 1, r.rev ^= 1; swap(l.ls, l.rs), swap(r.ls, r.rs); swap(l.s[0], l.s[1]), swap(r.s[0], r.s[1]); } } void rotate(int x) { int y = tr[x].p, z = tr[y].p; int k = tr[y].s[1] == x; tr[z].s[tr[z].s[1] == y] = x, tr[x].p = z; tr[y].s[k] = tr[x].s[k ^ 1], tr[tr[x].s[k ^ 1]].p = y; tr[x].s[k ^ 1] = y, tr[y].p = x; pushup(y), pushup(x); } void splay(int x, int k) { while (tr[x].p != k) { int y = tr[x].p, z = tr[y].p; if (z != k) if ((tr[y].s[1] == x) ^ (tr[z].s[1] == y)) rotate(x); else rotate(y); rotate(x); } if (!k) root = x; } int get_k(int k) { int u = root; while (u) { pushdown(u); if (tr[tr[u].s[0]].size >= k) u = tr[u].s[0]; else if (tr[tr[u].s[0]].size + 1 == k) return u; else k -= tr[tr[u].s[0]].size + 1, u = tr[u].s[1]; } } int build(int l, int r, int p) { int mid = l + r >> 1; int u = nodes[tt -- ]; tr[u].init(w[mid], p); if (l < mid) tr[u].s[0] = build(l, mid - 1, u); if (mid < r) tr[u].s[1] = build(mid + 1, r, u); pushup(u); return u; } void dfs(int u) { if (tr[u].s[0]) dfs(tr[u].s[0]); if (tr[u].s[1]) dfs(tr[u].s[1]); nodes[ ++ tt] = u; } int main() { for (int i = 1; i < N; i ++ ) nodes[ ++ tt] = i; scanf("%d%d", &n, &m); tr[0].ms = w[0] = w[n + 1] = -INF; for (int i = 1; i <= n; i ++ ) scanf("%d", &w[i]); root = build(0, n + 1, 0); char op[20]; while (m -- ) { scanf("%s", op); if (!strcmp(op, "INSERT")) { int posi, tot; scanf("%d%d", &posi, &tot); for (int i = 0; i < tot; i ++ ) scanf("%d", &w[i]); int l = get_k(posi + 1), r = get_k(posi + 2); splay(l, 0), splay(r, l); int u = build(0, tot - 1, r); tr[r].s[0] = u; pushup(r), pushup(l); } else if (!strcmp(op, "DELETE")) { int posi, tot; scanf("%d%d", &posi, &tot); int l = get_k(posi), r = get_k(posi + tot + 1); splay(l, 0), splay(r, l); dfs(tr[r].s[0]); tr[r].s[0] = 0; pushup(r), pushup(l); } else if (!strcmp(op, "MAKE-SAME")) { int posi, tot, c; scanf("%d%d%d", &posi, &tot, &c); int l = get_k(posi), r = get_k(posi + tot + 1); splay(l, 0), splay(r, l); auto& son = tr[tr[r].s[0]]; son.same = 1, son.v = c, son.sum = c * son.size; if (c > 0) son.ms = son.ls = son.rs = son.sum; else son.ms = c, son.ls = son.rs = 0; pushup(r), pushup(l); } else if (!strcmp(op, "REVERSE")) { int posi, tot; scanf("%d%d", &posi, &tot); int l = get_k(posi), r = get_k(posi + tot + 1); splay(l, 0), splay(r, l); auto& son = tr[tr[r].s[0]]; son.rev ^= 1; swap(son.ls, son.rs); swap(son.s[0], son.s[1]); pushup(r), pushup(l); } else if (!strcmp(op, "GET-SUM")) { int posi, tot; scanf("%d%d", &posi, &tot); int l = get_k(posi), r = get_k(posi + tot + 1); splay(l, 0), splay(r, l); printf("%d\n", tr[tr[r].s[0]].sum); } else printf("%d\n", tr[root].ms); } return 0; }
#include<iostream> #include<algorithm> #include <cstring> #include <cstdio> #define ls(x) tr[x].s[0] #define rs(x) tr[x].s[1] #define sz(x) tr[x].size #define fa(x) tr[x].p using namespace std; const int N = 1000100,Inf=1e9; struct Node { int s[2], p, v; int rev, same; int size, sum, ms, ls, rs; void init(int _v, int _p) { s[0] = s[1] = 0, p = _p, v = _v; rev = same = 0; size = 1, sum = ms = v; ls = rs = max(v, 0); } }tr[N]; int root,cnt,m,n; int a[N],w[N]; void pushup(int x) { auto &u = tr[x], &l = tr[u.s[0]], &r = tr[u.s[1]]; u.size = l.size + r.size + 1; u.sum = l.sum + r.sum + u.v; u.ls = max(l.ls, l.sum + u.v + r.ls); u.rs = max(r.rs, r.sum + u.v + l.rs); u.ms = max(max(l.ms, r.ms), l.rs + u.v + r.ls); } void pushdown(int x) { Node &u = tr[x], &l = tr[u.s[0]], &r = tr[u.s[1]]; if (u.same) { u.same = u.rev = 0; if (u.s[0]) l.same = 1, l.v = u.v, l.sum = l.v * l.size; if (u.s[1]) r.same = 1, r.v = u.v, r.sum = r.v * r.size; if (u.v > 0) { if (u.s[0]) l.ms = l.ls = l.rs = l.sum; if (u.s[1]) r.ms = r.ls = r.rs = r.sum; } else { if (u.s[0]) l.ms = l.v, l.ls = l.rs = 0; if (u.s[1]) r.ms = r.v, r.ls = r.rs = 0; } } else if (u.rev) { u.rev = 0, l.rev ^= 1, r.rev ^= 1; swap(l.ls, l.rs), swap(r.ls, r.rs); swap(l.s[0], l.s[1]), swap(r.s[0], r.s[1]); } } void rotate(int x) { int y = fa(x), z = fa(y); int k = rs(y) == x; tr[z].s[rs(z) == y] = x, fa(x) = z; tr[y].s[k] = tr[x].s[k ^ 1], tr[tr[x].s[k ^ 1]].p = y; tr[x].s[k^1]=y,fa(y)=x; pushup(y), pushup(x); } void splay(int x,int k) { while (fa(x) != k) { int y = fa(x), z = fa(y); if (z != k) { if ((rs(y) == x) ^ (rs(z) == y)) rotate(x); else rotate(y); } rotate(x); } if (!k) root = x; } int get_k(int k) { int u = root; while (u) { pushdown(u); if (sz(ls(u)) >= k) u = ls(u); else if (sz(ls(u)) + 1 == k) return u; else k -= sz(ls(u)) + 1, u = rs(u); } } int build(int l,int r,int p) { int mid = l + r >> 1; int u = a[cnt--]; tr[u].init(w[mid], p); if (l < mid) ls(u) = build(l, mid - 1, u); if (mid < r) rs(u) = build(mid + 1, r, u); pushup(u); return u; } void dfs(int u) { if (ls(u)) dfs(ls(u)); if (rs(u)) dfs(rs(u)); a[++cnt] = u; } int tcin; int main() { for (int i = 1; i < N; i ++ ) a[ ++ cnt] = i; scanf("%d%d", &n, &m); tr[0].ms = w[0] = w[n + 1] = -Inf; for (int i = 1; i <= n; i ++ ) scanf("%d", &w[i]); root = build(0, n + 1, 0); char op[20]; while (m -- ) { scanf("%s", op); if (!strcmp(op, "INSERT")) { int posi, tot; scanf("%d%d", &posi, &tot); for (int i = 0; i < tot; i ++ ) scanf("%d", &w[i]); int l = get_k(posi + 1), r = get_k(posi + 2); splay(l, 0), splay(r, l); int u = build(0, tot - 1, r); tr[r].s[0] = u; pushup(r), pushup(l); } else if (!strcmp(op, "DELETE")) { int posi, tot; scanf("%d%d", &posi, &tot); int l = get_k(posi), r = get_k(posi + tot + 1); splay(l, 0), splay(r, l); dfs(tr[r].s[0]); tr[r].s[0] = 0; pushup(r), pushup(l); } else if (!strcmp(op, "MAKE-SAME")) { int posi, tot, c; scanf("%d%d%d", &posi, &tot, &c); int l = get_k(posi), r = get_k(posi + tot + 1); splay(l, 0), splay(r, l); auto& son = tr[tr[r].s[0]]; son.same = 1, son.v = c, son.sum = c * son.size; if (c > 0) son.ms = son.ls = son.rs = son.sum; else son.ms = c, son.ls = son.rs = 0; pushup(r), pushup(l); } else if (!strcmp(op, "REVERSE")) { int posi, tot; scanf("%d%d", &posi, &tot); int l = get_k(posi), r = get_k(posi + tot + 1); splay(l, 0), splay(r, l); auto& son = tr[tr[r].s[0]]; son.rev ^= 1; swap(son.ls, son.rs); swap(son.s[0], son.s[1]); pushup(r), pushup(l); } else if (!strcmp(op, "GET-SUM")) { int posi, tot; scanf("%d%d", &posi, &tot); int l = get_k(posi), r = get_k(posi + tot + 1); splay(l, 0), splay(r, l); printf("%d\n", tr[tr[r].s[0]].sum); } else printf("%d\n", tr[root].ms); } return 0; }
本文在博客园发布,作者:limited_Infinite,转载请注明原文链接:https://www.cnblogs.com/limitedInfinite/p/15014806.html