社区讨论
求助, 样例通过, 提交0分
P2042[NOI2005] 维护数列参与者 4已保存回复 4
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 4 条
- 当前快照
- 1 份
- 快照标识符
- @mi7xrlia
- 此快照首次捕获于
- 2025/11/21 05:21 4 个月前
- 此快照最后确认于
- 2025/11/21 05:21 4 个月前
CPP
#include<stdio.h>
#include<string.h>
#define N 4000005
int val[N], size[N], cnt[N], ch[N][2], par[N], sum[N];
int rev[N], tag[N], mx[N], lx[N], rx[N], ncnt, root, I[N];
inline int max(int a, int b) { return (a > b) ? a : b; }
inline int chk(int x) { return ch[par[x]][1] == x; }
inline void swap(int &a, int &b) { a ^= b, b ^= a, a ^= b; }
inline void pushUp(int p) {
int l = ch[p][0], r = ch[p][1];
sum[p] = sum[l] + sum[r] + val[p], size[p] = size[l] + size[r] + 1;
lx[p] = max(lx[l], sum[l] + val[p] + lx[r]);
rx[p] = max(rx[r], sum[r] + val[p] + rx[l]);
mx[p] = max(mx[l], max(mx[r], rx[l] + val[p] + lx[r]));
}
inline void pushDown(int x) {
int l = ch[x][0], r = ch[x][1];
if(tag[x]) {
rev[x] = tag[x] = 0;
if(l) tag[l] = 1, val[l] = val[x], sum[l] = val[l] * size[l];
if(r) tag[r] = 1, val[r] = val[x], sum[r] = val[r] * size[r];
if(val[x] > 0) {
if(l) lx[l] = rx[l] = mx[l] = sum[l];
if(r) lx[r] = rx[r] = mx[r] = sum[r];
} else {
if(l) lx[l] = rx[l] = 0, mx[l] = val[x];
if(r) lx[r] = rx[r] = 0, mx[r] = val[x];
}
}
if(rev[x]) {
rev[x] = 0;
if(l) swap(lx[l], rx[l]), swap(ch[l][0], ch[l][1]), rev[l] ^= 1;
if(r) swap(lx[r], rx[r]), swap(ch[r][0], ch[r][1]), rev[r] ^= 1;
}
pushUp(x);
}
inline void rotate(int x) {
int y = par[x], z = par[y], k = chk(x), w = ch[x][!k];
ch[y][k] = w, par[w] = y, ch[z][chk(y)] = x, par[x] = z;
ch[x][!k] = y, par[y] = x; pushUp(y); pushUp(x);
}
inline void splay(int x, int goal = 0) {
for(;par[x] != goal;rotate(x)) {
int y = par[x], z = par[y];
if(z != goal) rotate((chk(x) == chk(y)) ? y : x);
}
if(!goal) root = x;
}
inline int kth(int x) {
int cur = root;
while(true) {
pushDown(cur);
if(x <= size[ch[cur][0]] && ch[cur][0]) cur = ch[cur][0];
else if(x > size[ch[cur][0]] + 1) x -= size[ch[cur][0]] + 1, cur = ch[cur][1];
else return cur;
}
}
inline int build(int *s, int l, int r, int fa) {
if(l > r) return 0;
int mid = (l + r) >> 1, cur = ++ncnt;
ch[cur][0] = build(s, l, mid - 1, cur), ch[cur][1] = build(s, mid + 1, r, cur);
val[cur] = s[mid], par[cur] = fa, size[cur] = cnt[cur] = 1, rev[cur] = tag[cur] = 0; pushUp(cur); return cur;
}
inline int split(int l, int r) {
int x = kth(l), y = kth(r);
splay(x); splay(y, x);
return y;
}
inline void insert(int l, int len) {
int y = split(l + 1, l + 2);
int t = build(I, 1, len, ++ncnt);
par[t] = y, ch[y][0] = t;
pushUp(y); pushUp(par[y]);
}
inline void del(int l, int len) {
int y = split(l, l + len);
ch[y][0] = 0;
pushUp(y); pushUp(par[y]);
}
inline void makeSame(int l, int len, int k) {
int y = split(l, l + len + 1);
tag[ch[y][0]] = true, val[ch[y][0]] = k;
pushUp(y); pushUp(par[y]);
}
inline void reverse(int l, int len) {
int y = ch[split(l, l + len + 1)][0];
rev[y] ^= 1;
swap(ch[y][0], ch[y][1]);
swap(lx[y], rx[y]);
pushUp(y); pushUp(par[y]);
}
inline int getSum(int l, int len) {
int y = split(l, l + len + 1);
return sum[ch[y][0]];
}
inline int getMax() { return mx[root]; }
inline void write(int cur) {
// pushDown(cur);
if(ch[cur][0]) write(ch[cur][0]);
printf("%d ", val[cur]);
if(ch[cur][1]) write(ch[cur][1]);
// pushUp(cur);
}
int main(int argc, char** args) {
int n = 0, m = 0;
scanf("%d %d", &n, &m);
mx[0] = I[1] = I[n + 2] = -2147483647;
for(int i = 1;i <= n;i++) {
scanf("%d", &I[i + 1]);
}
root = build(I, 1, n + 2, 0);
char opt[1005] = {'\0'};
int x = 0, y = 0, z = 0;
for(int i = 1;i <= m;i++) {
scanf("%s", opt);
if(!strcmp(opt, "INSERT")) {
scanf("%d %d", &x, &y);
for(int p = 1;p <= y;p++) scanf("%d", &I[p]);
insert(x, y);
} else if(!strcmp(opt, "DELETE")) {
scanf("%d %d", &x, &y);
del(x, y);
} else if(!strcmp(opt, "MAKE-SAME")) {
scanf("%d %d %d", &x, &y, &z);
makeSame(x, y, z);
} else if(!strcmp(opt, "REVERSE")) {
scanf("%d %d", &x, &y);
reverse(x, y);
} else if(!strcmp(opt, "GET-SUM")) {
scanf("%d %d", &x, &y);
printf("%d\n", getSum(x, y));
} else {
printf("%d\n", getMax());
}
}
}
回复
共 4 条回复,欢迎继续交流。
正在加载回复...