首先声明是codevs写法,bzoj限制64M必须动态分配内存,否则妥妥地MLE(0ms就T了)
原题就不打了。
巨型splay模板题,省选前两天突击splay就拿这道题练了练手。练了提取区间、区间插入、删除、求和,都是基础的。有一个细节需要注意一点:下传翻转标记时一定要先传到子树的子树并立即交换左右子树,否则在splay的过程中会使带标记的子树“还没按标记修改就拿来修改它的父亲了”。操作6“wfwbz”已有详细介绍,此处不再赘述。Code:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 3000000, nil = 0, oo = 1000000000;
int fa[maxn], son[maxn][2], key[maxn], maxl[maxn], maxr[maxn], maxs[maxn], sum[maxn], s[maxn];
bool same[maxn], rev[maxn];
int n, m, root;
inline void read(int &a) {
int f = 1;
char ch = getchar();
a = 0;
while(ch < '0' || ch > '9') {
if(ch == '-') f = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9') {
a = a*10 + ch - 48;
ch = getchar();
}
a *= f;
}
inline void write(int a) {
int top = 0;
char ch[30];
if(a < 0) { putchar('-'); a = -a; }
do {
ch[top++] = a%10 + 48;
a /= 10;
} while(a);
while(top--) putchar(ch[top]);
putchar('\n');
}
inline void update(int x) {
s[x] = s[son[x][0]] + s[son[x][1]] + 1;
sum[x] = sum[son[x][0]] + sum[son[x][1]] + key[x];
maxs[x] = max(maxs[son[x][0]], maxs[son[x][1]]);
maxs[x] = max(maxs[x], maxl[son[x][1]] + key[x] + maxr[son[x][0]]);
maxl[x] = max(maxl[son[x][0]], sum[son[x][0]] + key[x] + maxl[son[x][1]]);
maxr[x] = max(maxr[son[x][1]], sum[son[x][1]] + key[x] + maxr[son[x][0]]);
}
inline void rotate(int x, int w) {
int y = fa[x];
son[y][w^1] = son[x][w];
if(son[x][w] != 0) fa[son[x][w]] = y;
fa[x] = fa[y];
if(fa[y] != nil)
if(y == son[fa[y]][0]) son[fa[y]][0] = x;
else son[fa[y]][1] = x;
son[x][w] = y;
fa[y] = x;
update(y); update(x);
}
inline void splay(int x, int poi) {
if(x == nil) return;
while(fa[x] != poi) {
if(fa[fa[x]] == poi)
if(x == son[fa[x]][0]) rotate(x, 1);
else rotate(x, 0);
else
if(fa[x] == son[fa[fa[x]]][0])
if(x == son[fa[x]][0])
{ rotate(fa[x], 1); rotate(x, 1); }
else
{ rotate(x, 0); rotate(x, 1); }
else
if(x == son[fa[x]][0])
{ rotate(x, 1); rotate(x, 0); }
else
{ rotate(fa[x], 0); rotate(x, 0); }
}
if(poi == nil) root = x;
}
inline void pushdown(int x) {
if(rev[x]) {
rev[x] = false;
rev[son[x][0]] ^= 1; rev[son[x][1]] ^= 1;
swap(maxl[son[x][0]], maxr[son[x][0]]);
swap(maxl[son[x][1]], maxr[son[x][1]]);
swap(son[son[x][0]][0], son[son[x][0]][1]);
swap(son[son[x][1]][0], son[son[x][1]][1]);
}
if(same[x]) {
if(son[x][0] != nil) {
key[son[x][0]] = key[x];
sum[son[x][0]] = key[x]*s[son[x][0]];
same[son[x][0]] = true;
if(key[x] >= 0) maxl[son[x][0]] = maxr[son[x][0]] = maxs[son[x][0]] = sum[son[x][0]];
else { maxl[son[x][0]] = maxr[son[x][0]] = 0; maxs[son[x][0]] = key[son[x][0]]; }
}
if(son[x][1] != nil) {
key[son[x][1]] = key[x];
sum[son[x][1]] = key[x]*s[son[x][1]];
same[son[x][1]] = true;
if(key[x] >= 0) maxl[son[x][1]] = maxr[son[x][1]] = maxs[son[x][1]] = sum[son[x][1]];
else { maxl[son[x][1]] = maxr[son[x][1]] = 0; maxs[son[x][1]] = key[son[x][1]]; }
}
same[x] = false;
}
}
void build(int l, int r, int fater, bool ch) {
if(l > r) return;
int rot = ((l + r) >> 1);
son[fater][ch] = rot; fa[rot] = fater;
build(l, rot-1, rot, 0); build(rot+1, r, rot, 1);
update(rot);
}
inline int find(int x, int k) {
pushdown(x);
if(k == s[son[x][0]] + 1) return x;
if(k <= s[son[x][0]]) return find(son[x][0], k);
else return find(son[x][1], k - s[son[x][0]] - 1);
}
int pos, tot, c;
char cst[20];
void insert() {
for(int i = n+1; i <= n+tot; ++i) read(key[i]);
splay(find(root, pos+1), nil); splay(find(root, pos+2), root);
build(n+1, n+tot, son[root][1], 0);
n += tot;
update(son[root][1]); update(root);
}
inline void dlete() {
splay(find(root, pos), nil); splay(find(root, pos+tot+1), root);
son[son[root][1]][0] = nil;
update(son[root][1]); update(root);
}
inline void change() {
splay(find(root, pos), nil); splay(find(root, pos+tot+1), root);
int rot = son[son[root][1]][0];
key[rot] = c; sum[rot] = c*s[rot]; same[rot] = true;
if(c > 0) maxl[rot] = maxr[rot] = maxs[rot] = sum[rot];
else { maxl[rot] = maxr[rot] = 0; maxs[rot] = key[rot]; }
update(son[root][1]); update(root);
}
inline void rever() {
splay(find(root, pos), nil); splay(find(root, pos+tot+1), root);
int rot = son[son[root][1]][0];
if(!same[root]) {
rev[rot] ^= 1;
swap(son[rot][0], son[rot][1]);
swap(maxl[rot], maxr[rot]);
}
update(son[root][1]); update(root);
}
inline int querysum() {
splay(find(root, pos), nil); splay(find(root, pos+tot+1), root);
return sum[son[son[root][1]][0]];
}
inline int querylst() {
return maxs[root];
}
int main() {
read(n); read(m); n += 2;
for(int i = 2; i < n; ++i) read(key[i]);
key[1] = key[n] = maxs[nil] = -oo;
build(1, n, 0, 0); root = ((n + 1) >> 1);
for(int i = 1; i <= m; ++i) {
scanf("%s", &cst);
switch(cst[2]) {
case 'S' :read(pos); read(tot); insert(); break;
case 'L' :read(pos); read(tot); dlete(); break;
case 'K' :read(pos); read(tot); read(c); change(); break;
case 'V' :read(pos); read(tot); rever(); break;
case 'T' :read(pos); read(tot); write(querysum()); break;
case 'X' :write(querylst()); break;
default :;
}
}
return 0;
}