嘛。。。又是屯了一年多的题。。。然而之前太弱了调不出来QAQ
随便一个可以提取区间的平衡树都可以搞这道题。
然而这题的splay我写过3个版本了。。。QAQ
为了写WC2016的T3,用treap写了一发这题练练手。
似乎没啥东西需要注意的。代码还好长,以后想办法缩一缩吧。。。
#include
using namespace std;
#define rep(i,a,b) for (int i = a , _ = b ; i <= _ ; i ++)
#define per(i,a,b) for (int i = a , _ = b ; i >= _ ; i --)
#define maxn 500007
inline int rd() {
char c = getchar();
while (!isdigit(c) && c != '-') c = getchar() ; int x = 0 , f = 1;
if (c == '-') f = -1; else x = c - '0';
while (isdigit(c = getchar())) x = x * 10 + c - '0';
return x * f;
}
inline int rnd() {
static int rand_seed = 1542071823;
rand_seed += rand_seed << 1 | 1;
return rand_seed;
}
inline void upmax(int&a , int b) { if (a < b) a = b ; }
const int inf = 2000000000;
int n , m , a[maxn];
void input() {
n = rd() , m = rd();
rep (i , 1 , n) a[i] = rd();
}
#define fir first
#define sec second
static int DBG_CLOCK = 0;
namespace Treap {
struct node;
node *nil;
struct node{
node *l , *r;
int key , pri , rv , cv , sz;
int s , ls , rs , ms;
node(int _key = 0): key(_key) , pri(rnd()) , l(nil) , r(nil) , rv(0) , cv(1001) , sz(1) { s = ls = rs = ms = key; }
inline void upd() {
sz = l->sz + r->sz + 1;
s = l->s + r->s + key;
ls = max(l->ls , l->s + key + max(0 , r->ls));
rs = max(r->rs , r->s + key + max(0 , l->rs));
ms = max(0 , l->rs) + key + max(0 , r->ls);
assert(ms < inf);
upmax(ms , max(l->ms , r->ms));
assert(ms < inf);
}
inline void tag(int v) {
if (this == nil) return;
key = v , s = v * sz;
ls = rs = ms = max(s , v);
cv = v;
}
inline void rev() {
if (this == nil) return;
swap(l , r);
swap(ls , rs);
rv ^= 1;
}
inline void push() {
if (this == nil) return;
if (cv != 1001) {
l -> tag(cv) , r -> tag(cv);
cv = 1001;
}
if (rv) {
l -> rev() , r -> rev();
rv = 0;
}
}
}data_pool[maxn] , *mem_pool[maxn] , *rt;
int pool_top , data_top;
typedef pair data;
inline node *newnode(int key) {
node *u;
if (pool_top)
u = mem_pool[pool_top --];
else
u = &data_pool[data_top ++];
*u = node(key);
return u;
}
inline void delnode(node *u) {
mem_pool[++ pool_top] = u;
}
node *build(int *a , int n) {
static node *stack[maxn] , *u , *pre;
int top = 0;
rep (i , 1 , n) {
u = newnode(a[i]);
pre = nil;
while (top && stack[top]->pri > u->pri) {
stack[top] -> upd();
pre = stack[top];
stack[top --] = nil;
}
if (top) stack[top] -> r = u;
u -> l = pre;
stack[++ top] = u;
}
while (top) stack[top --] -> upd();
return stack[1];
}
node *join(node *u , node *v) {
if (u == nil) return v;
if (v == nil) return u;
if (u->pri < v->pri) {
u -> push();
u -> r = join(u -> r , v);
u -> upd();
return u;
} else {
v -> push();
v -> l = join(u , v -> l);
v -> upd();
return v;
}
}
data split(node *u , int k) {
if (u == nil) return data(nil , nil);
data t;
u -> push();
if (u->l->sz >= k) {
t = split(u -> l , k);
u -> l = t.sec , t.sec = u;
} else {
t = split(u -> r , k - u->l->sz - 1);
u -> r = t.fir , t.fir = u;
}
u -> upd();
return t;
}
void remove(node *u) {
if (u == nil) return;
remove(u -> l) , remove(u -> r);
delnode(u);
}
}
using namespace Treap;
int pos , cnt;
inline void insert_() {
rep (i , 1 , cnt) a[i] = rd();
node *nr = build(a , cnt);
data t = split(rt , pos);
rt = join(join(t.fir , nr) , t.sec);
}
inline void delete_() {
data t1 = split(rt , pos + cnt - 1) , t2 = split(t1.fir , pos - 1);
remove(t2.sec);
rt = join(t2.fir , t1.sec);
}
inline void reverse_() {
data t1 = split(rt , pos + cnt - 1) , t2 = split(t1.fir , pos - 1);
t2.sec -> rev();
rt = join(join(t2.fir , t2.sec) , t1.sec);
}
inline void mk_same_() {
int v = rd();
data t1 = split(rt , pos + cnt - 1) , t2 = split(t1.fir , pos - 1);
t2.sec -> tag(v);
rt = join(join(t2.fir , t2.sec) , t1.sec);
}
inline void get_sum_() {
data t1 = split(rt , pos + cnt - 1) , t2 = split(t1.fir , pos - 1);
printf("%d\n" , t2.sec -> s);
rt = join(join(t2.fir , t2.sec) , t1.sec);
}
inline void max_sum_() {
printf("%d\n" , rt -> ms);
}
void solve() {
nil = newnode(-inf);
nil -> sz = nil -> s = 0;
rt = build(a , n);
char cmd[20];
rep (i , 1 , m) {
scanf("%s" , cmd);
if (cmd[2] != 'X') pos = rd() , cnt = rd();
switch (cmd[2]) {
case 'S' : insert_ (); break ;
case 'L' : delete_ (); break ;
case 'V' : reverse_(); break ;
case 'T' : get_sum_(); break ;
case 'X' : max_sum_(); break ;
case 'K' : mk_same_(); break ;
}
}
}
int main() {
#ifndef ONLINE_JUDGE
freopen("data.txt" , "r" , stdin);
#endif
input();
solve();
return 0;
}