时隔半年我又来写这道题了,这次的Splay模版简练多了。有好多种操作,注意垃圾回收。
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <string>
#include <cstring>
#include <cmath>
#define Rep(i, x, y) for (int i = x; i <= y; i ++)
#define RepE(i, x) for (int i = pos[x]; i; i = g[i].nex)
#define N 500005
#define u t[x]
#define lc t[x].ch[0]
#define rc t[x].ch[1]
#define Lc t[lc]
#define Rc t[rc]
#define Ts t[x].sum
#define tp t[x].par
#define Tp t[tp]
#define Tz t[x].lz
using namespace std;
typedef long long LL;
const int inf = 10000;
int n, m, sz, a[N], rt, b[N];
struct arr {
int ch[2], par, ml, mr, mx, sum, lz, num, v; bool rv;
void Set(int x) { ml = mr = mx = ch[0] = ch[1] = par = sum = rv = 0, v = x, lz = inf; }
} t[N];
void PD(int x) {
if (!x) return ;
if (Tz != inf) {
Lc.lz = Rc.lz = u.v = Tz;
u.sum = Tz * u.num;
u.mx = (Tz < 0) ? Tz : t[x].sum;
u.ml = u.mr = max(0, u.mx);
Tz = inf;
}
if (t[x].rv) {
u.rv = 0, swap(lc, rc), Lc.rv ^= 1, Rc.rv ^= 1;
swap(u.ml, u.mr);
}
}
void Upd(int x) {
if (!x) return ;
PD(x), PD(lc), PD(rc);
Ts = Lc.sum + Rc.sum + u.v;
u.num = Lc.num + Rc.num + 1;
u.ml = max(Lc.ml, Lc.sum + u.v + max(Rc.ml, 0));
u.mr = max(Rc.mr, Rc.sum + u.v + max(Lc.mr, 0));
u.mx = max(Lc.mx, max(Rc.mx, max(Lc.mr, 0) + u.v + max(0, Rc.ml)));
}
void Sc(int x, int y, bool f) { if (x) u.ch[f] = y; t[y].par = x; }
inline bool d(int x) { return Tp.ch[1] == x; }
void Rot(int x) {
int y = tp, z = Tp.par, ty = d(x);
Sc(z, x, d(y)), Sc(y, t[x].ch[!ty], ty), Sc(x, y, !ty), Upd(y);// Upd(x);
}
void Splay(int x, int z = 0) {
PD(x); if (!z) rt = x;
while (tp != z) {
PD(tp), PD(x);
if (Tp.par == z) { Rot(x); break ; }
(d(x) == d(tp)) ? (Rot(tp), Rot(x)) : (Rot(x), Rot(x));
} Upd(x);
}
int Build(int l, int r) {
if (l > r) return 0;
int x = b[++ sz];
int mid = (l + r) >> 1;
u.Set(a[mid]);
lc = Build(l, mid-1), rc = Build(mid+1, r);
Lc.par = Rc.par = x, Tz = inf, Upd(x);
return x;
}
int Find(int x, int y) {
PD(x);
if (Lc.num + 1 < y) return Find(rc, y-(Lc.num+1));
else if (Lc.num + 1 == y) return x;
else return Find(lc, y);
}
int Get(int x, int y) {
x ++, y ++;
int x1 = Find(rt, x), x2 = Find(rt, y);
Splay(x1, 0), Splay(x2, x1), Upd(rt);
return x2;
}
void Del(int x) {
if (!x) return ;
b[sz --] = x, Del(lc), Del(rc);
}
int main()
{
scanf ("%d%d", &n, &m);
Rep(i, 1, N-1) b[i] = i;
Rep(i, 1, n) scanf ("%d", &a[i]);
a[0] = a[n+1] = -inf;
t[0].mx = -inf;
rt = Build(0, n+1);
char str[15];
Rep(i, 1, m) {
scanf ("%s", str);
int x, y, z, x2;
if (str[0] == 'I') {
scanf ("%d%d", &x, &n);
Rep(j, 1, n) {
scanf ("%d", &a[j]);
}
x = Get(x, x+1);
Sc(x, Build(1, n), 0), Upd(x), Upd(rt);
} else if (str[0] == 'D') {
scanf ("%d%d", &x, &y);
x = Get(x-1, x+y);
Del(lc);
t[x].ch[0] = 0, Upd(x), Upd(rt);
} else if (str[0] == 'M' && str[2] == 'K') {
scanf ("%d%d%d", &x, &y, &z);
x = Get(x-1, x+y), Lc.lz = z, Upd(lc), Upd(x), Upd(rt);
} else if (str[0] == 'R') {
scanf ("%d%d", &x, &y);
x = Get(x-1, x+y), Lc.rv ^= 1, Upd(lc), Upd(x), Upd(rt);
} else if (str[0] == 'G') {
scanf ("%d%d", &x, &y);
x = Get(x-1, x+y);
printf("%d\n", Lc.sum);
} else {
Upd(rt), printf ("%d\n", t[rt].mx);
}
}
return 0;
}