题目描述
请写一个程序,要求维护一个数列,支持以下 6 种操作:(请注意,格式栏 中的下划线‘ _ ’表示实际输入文件中的空格)
输入输出格式
输入格式:
输入文件的第 1 行包含两个数 N 和 M,N 表示初始时数列中数的个数,M 表示要进行的操作数目。 第 2 行包含 N 个数字,描述初始时的数列。 以下 M 行,每行一条命令,格式参见问题描述中的表格
输出格式:
对于输入数据中的 GET-SUM 和 MAX-SUM 操作,向输出文件依次打印结 果,每个答案(数字)占一行。
输入输出样例
输入样例#1: 复制
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: 复制
-1 10 1 10
说明
你可以认为在任何时刻,数列中至少有 1 个数。
输入数据一定是正确的,即指定位置的数在数列中一定存在。
50%的数据中,任何时刻数列中最多含有 30 000 个数;
100%的数据中,任何时刻数列中最多含有 500 000 个数。
100%的数据中,任何时刻数列中任何一个数字均在[-1 000, 1 000]内。
100%的数据中,M ≤20 000,插入的数字总数不超过 4 000 000 。
平衡树裸题,就是写的有点蛋疼……维护和最大的一串的话,就按基本套路。左端点开始的最大,右端点开始的最大中间的最大。每一次查询root就可以了。
#include<cstdio>
#include<queue>
#include<algorithm>
using namespace std;
const int maxn = 5e5 + 5;
const int inf = 0x3f3f3f3f >> 1;
char s[10];
namespace Splay {
const int L = 0, R = 1;
struct node {
int ch[2], size, num, fa;
int sum, edit, rev, Lmax, Rmax, Mmax;
}tree[maxn];
queue<int > Mempool;
int root, cnt, null;
int Newnode() {
if(Mempool.empty()) return ++cnt;
null = Mempool.front(); Mempool.pop();
return tree[null] = (node){}, tree[null].edit = -inf, null;
}
void push_up(int rt) {
int tl = tree[rt].ch[L], tr = tree[rt].ch[R];
tree[rt].sum = tree[tl].sum + tree[tr].sum + tree[rt].num;
tree[rt].Lmax = max(tree[tl].sum + tree[rt].num + tree[tr].Lmax, tree[tl].Lmax);
tree[rt].Rmax = max(tree[tr].sum + tree[rt].num + tree[tl].Rmax, tree[tr].Rmax);
tree[rt].Mmax = max(max(tree[tl].Mmax, tree[tr].Mmax), tree[tl].Rmax + tree[rt].num + tree[tr].Lmax);
tree[rt].size = tree[tl].size + tree[tr].size + 1;
}
void push_down(int rt) {
int tl = tree[rt].ch[L], tr = tree[rt].ch[R];
if(tree[rt].edit >= -100000) {
int w = tree[rt].edit, sz = tree[rt].size;
tree[tl].edit = tree[tl].num = tree[tr].edit = tree[tr].num = w;
tree[rt].rev = tree[tl].rev = tree[tr].rev = 0;
tree[tl].sum = w * tree[tl].size, tree[tr].sum = w * tree[tr].size;
if(tl) {
tree[tl].Lmax = tree[tl].Rmax = max(tree[tl].sum, 0);
tree[tl].Mmax = max(tree[tl].sum, w);
}
if(tr) {
tree[tr].Lmax = tree[tr].Rmax = max(tree[tr].sum, 0);
tree[tr].Mmax = max(tree[tr].sum, w);
}
tree[rt].edit = -inf;
} else if(tree[rt].rev) {
tree[tl].rev ^= 1, tree[tr].rev ^= 1;
swap(tree[rt].ch[L], tree[rt].ch[R]);
swap(tree[tl].Lmax, tree[tl].Rmax);
swap(tree[tr].Lmax, tree[tr].Rmax);
tree[rt].rev = 0;
}
}
void recyc(int rt) {
Mempool.push(rt);
if(tree[rt].ch[L]) recyc(tree[rt].ch[L]);
if(tree[rt].ch[R]) recyc(tree[rt].ch[R]);
}
void rotate(int rt) {
int p = tree[rt].fa, a = tree[p].fa;
int r = tree[p].ch[R] == rt, l = r ^ 1;
if(a) tree[a].ch[tree[a].ch[R] == p] = rt;
tree[rt].fa = a, tree[p].fa = rt, tree[tree[rt].ch[l]].fa = p;
tree[p].ch[r] = tree[rt].ch[l], tree[rt].ch[l] = p;
push_up(p), push_up(rt);
}
void splay(int rt, int y) {
int des = tree[y].fa;
while(tree[rt].fa != des) {
int p = tree[rt].fa, a = tree[p].fa;
push_down(p), push_down(rt);
if(p != y) {
if((tree[a].ch[R] == p) ^ (tree[p].ch[R] == rt)) rotate(rt);
else rotate(p);
}
rotate(rt);
}
if(y == root) root = rt;
push_up(rt);
}
int qnode(int rank) {
int now = root;
++rank, push_down(now);
for(int tl = tree[now].ch[L]; now; push_down(now), tl = tree[now].ch[L]) {
if(rank <= tree[tl].size) now = tl;
else if(rank > tree[tl].size + 1)
rank -= tree[tl].size + 1, now = tree[now].ch[R];
else return now;
}
return now;
}
void Rev(int l, int r) {
int ls = qnode(l - 1), rs = qnode(r + 1), rt;
splay(ls, root), splay(rs, tree[ls].ch[R]);
tree[rt = tree[rs].ch[L]].rev ^= 1;
swap(tree[rt].Lmax, tree[rt].Rmax);
push_up(rs), push_up(ls);
}
void build(int & rt, int l, int r, int last, int * arr) {
int mid = l + r >> 1, w = arr[mid];
rt = Newnode();
if(l == r) {
tree[rt].size = 1;
tree[rt].rev = 0, tree[rt].sum = w;
}
tree[rt].Lmax = tree[rt].Rmax = max(w, 0);
tree[rt].Mmax = w, tree[rt].edit = -inf;
tree[rt].num = w, tree[rt].fa = last;
if(l < mid) build(tree[rt].ch[L], l, mid - 1, rt, arr);
if(r > mid) build(tree[rt].ch[R], mid + 1, r, rt, arr);
if(tree[rt].size != 1) push_up(rt);
}
void Ins(int n, int pos, int * arr) {
if(!n) return;
int pr = qnode(pos), su = qnode(pos + 1);
splay(pr, root), splay(su, tree[root].ch[R]);
build(tree[su].ch[L], 1, n, su, arr);
push_up(su), push_up(pr);
}
void Del(int pos, int len) {
if(!len) return;
int pr = qnode(pos - 1), su = qnode(pos + len);
splay(pr, root), splay(su, tree[root].ch[R]), recyc(tree[su].ch[L]);
tree[su].ch[L] = 0, push_up(su), push_up(pr);
}
void Edit(int pos, int len, int w) {
if(!len) return;
int pr = qnode(pos - 1), su = qnode(pos + len);
splay(pr, root), splay(su, tree[root].ch[R]);
int now = tree[su].ch[L];
tree[now].edit = tree[now].num = w;
tree[now].sum = tree[now].size * w;
tree[now].Lmax = tree[now].Rmax = max(tree[now].sum, 0);
tree[now].Mmax = max(tree[now].sum, w);
push_up(su), push_up(pr);
}
int GetSum(int pos, int len) {
if(!len) return 0;
int pr = qnode(pos - 1), su = qnode(pos + len);
splay(pr, root), splay(su, tree[root].ch[R]);
return tree[tree[su].ch[L]].sum;
}
}
int n, m, u, v, arr[maxn], a, b, c;
int main() {
using namespace Splay;
scanf("%d%d", &n, &m);
tree[0].Mmax = arr[0] = arr[n + 1] = -inf;
tree[0].Mmax = -inf;
for(register int i = 1; i <= n; ++i) scanf("%d", &arr[i]);
build(root, 0, n + 1, 0, arr);
while(m--) {
scanf("%s", s);
if(s[2] == 'X') {
printf("%d\n", tree[root].Mmax);
} else {
scanf("%d%d", &a, &b);
if(s[2] == 'S') {
for(register int i = 1; i <= b; ++i) scanf("%d", &arr[i]);
Ins(b, a, arr);
} else if(s[2] == 'L') Del(a, b);
else if(s[2] == 'K') scanf("%d", &c), Edit(a, b, c);
else if(s[2] == 'V') Rev(a, a + b - 1);
else if(s[2] == 'T') printf("%d\n", GetSum(a, b));
}
}
return 0;
}
rockdu
没有帐号? 立即注册