Description
Input
输入的第1 行包含两个数N 和M(M ≤20 000),N 表示初始时数列中数的个数,M表示要进行的操作数目。
第2行包含N个数字,描述初始时的数列。
以下M行,每行一条命令,格式参见问题描述中的表格。
任何时刻数列中最多含有500 000个数,数列中任何一个数字均在[-1 000, 1 000]内。
插入的数字总数不超过4 000 000个,输入文件大小不超过20MBytes。Output
对于输入数据中的GET-SUM和MAX-SUM操作,向输出文件依次打印结果,每个答案(数字)占一行。Sample Input
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-SUMSample Output
-1
10
1
10HINT
好好想想吧.. 这道题就是splay很多操作的题目.. 就是很难调很难打而已..
记住要初始化啊.. 我错了一天..
怒敲150+行..
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;
const int Maxn = 500010;
int ls[Maxn], rs[Maxn], ms[Maxn], id[Maxn], tp, sum[Maxn], fa[Maxn], size[Maxn], rev[Maxn], c[Maxn][2];
bool tag[Maxn];
int n, m;
int a[Maxn], rt, val[Maxn];
int _max ( int x, int y ){ return x > y ? x : y; }
void push_down ( int now ){
if ( now == 0 ) return;
int lc = c[now][0], rc = c[now][1];
if ( tag[now] ){
if ( val[now] > 0 ){
if ( lc > 0 ){
val[lc] = val[now];
ls[lc] = rs[lc] = ms[lc] = sum[lc] = val[now]*size[lc];
tag[lc] = 1;
}
if ( rc > 0 ){
val[rc] = val[now];
ls[rc] = rs[rc] = ms[rc] = sum[rc] = val[now]*size[rc];
tag[rc] = 1;
}
}
else {
if ( lc > 0 ){
val[lc] = val[now];
sum[lc] = val[now]*size[lc];
ls[lc] = rs[lc] = 0; ms[lc] = val[now];
tag[lc] = 1;
}
if ( rc > 0 ){
val[rc] = val[now];
sum[rc] = val[now]*size[rc];
ls[rc] = rs[rc] = 0; ms[rc] = val[now];
tag[rc] = 1;
}
}
tag[now] = 0; rev[now] = 0;
}
if ( rev[now] ){
rev[now] = 0;
rev[lc] ^= 1; rev[rc] ^= 1;
swap ( ls[lc], rs[lc] ); swap ( ls[rc], rs[rc] );
swap ( c[lc][0], c[lc][1] ); swap ( c[rc][0], c[rc][1] );
}
}
void update ( int now ){
int lc = c[now][0], rc = c[now][1];
ls[now] = _max ( ls[lc], sum[lc]+val[now]+ls[rc] );
rs[now] = _max ( rs[rc], sum[rc]+val[now]+rs[lc] );
size[now] = size[lc]+size[rc]+1;
sum[now] = sum[lc]+sum[rc]+val[now];
ms[now] = _max ( ms[lc], _max ( ms[rc], ls[rc]+val[now]+rs[lc] ) );
}
void clear ( int now ){ tag[now] = 0; val[now] = rev[now] = c[now][0] = c[now][1] = 0; }
void bulid ( int &now, int l, int r, int f ){
if ( l > r ){ now = 0; return; }
now = id[++tp];
clear (now);
if ( l == r ){
fa[now] = f;
if ( a[l] > 0 ) ls[now] = rs[now] = ms[now] = a[l];
else { ls[now] = rs[now] = 0; ms[now] = a[l]; }
sum[now] = val[now] = a[l];
size[now] = 1;
return;
}
fa[now] = f;
int mid = ( l + r ) >> 1;
val[now] = a[mid];
bulid ( c[now][0], l, mid-1, now );
bulid ( c[now][1], mid+1, r, now );
update (now);
}
void del ( int now ){
if ( now == 0 ) return;
id[tp--] = now;
del (c[now][0]); del (c[now][1]);
}
void rotate ( int x, int &k ){
int y = fa[x], z = fa[y], l, r;
if ( c[y][0] == x ) l = 0; else l = 1; r = l^1;
if ( y == k ) k = x;
else { if ( c[z][0] == y ) c[z][0] = x; else c[z][1] = x; }
fa[x] = z; fa[y] = x; fa[c[x][r]] = y;
c[y][l] = c[x][r]; c[x][r] = y;
update (y); update (x);
}
void splay ( int x, int &k ){
while ( x != k ){
int y = fa[x], z = fa[y];
if ( y != k ){
if ( (c[y][0]==x)^(c[z][0]==y) ) rotate ( x, k );
else rotate ( y, k );
}
rotate ( x, k );
}
}
int find ( int now, int rank ){
push_down (now);
int lc = c[now][0], rc = c[now][1];
if ( rank == size[lc]+1 ) return now;
else if ( rank <= size[lc] ) return find ( lc, rank );
else return find ( rc, rank-size[lc]-1 );
}
char s[11];
int main (){
int i, j, k;
for ( i = 1; i <= 500005; i ++ ) id[i] = i;
ms[0] = -1e9;
tp = 0;
scanf ( "%d%d", &n, &m );
for ( i = 2; i <= n+1; i ++ ) scanf ( "%d", &a[i] );
a[1] = a[n+2] = -1e9;
bulid ( rt, 1, n+2, 0 );
for ( i = 1; i <= m; i ++ ){
getchar ();
scanf ( "%s", s+1 );
if ( s[1] == 'I' ){
int x, tot;
scanf ( "%d%d", &x, &tot );
for ( j = 1; j <= tot; j ++ ) scanf ( "%d", &a[j] );
int p1 = find ( rt, x+1 );
int p2 = find ( rt, x+2 );
splay ( p1, rt );
splay ( p2, c[p1][1] );
push_down (p1); push_down (p2);
bulid ( c[p2][0], 1, tot, p2 );
update (p2); update (p1);
}
else if ( s[1] == 'D' ){
int x, tot;
scanf ( "%d%d", &x, &tot );
int p1 = find ( rt, x );
int p2 = find ( rt, x+tot+1 );
splay ( p1, rt );
splay ( p2, c[p1][1] );
del (c[p2][0]);
c[p2][0] = 0;
update (p2); update (p1);
}
else if ( s[1] == 'M' && s[3] == 'K' ){
int x, tot, cc;
scanf ( "%d%d%d", &x, &tot, &cc );
int p1 = find ( rt, x );
int p2 = find ( rt, x+tot+1 );
splay ( p1, rt );
splay ( p2, c[p1][1] );
tag[c[p2][0]] = 1; val[c[p2][0]] = cc;
sum[c[p2][0]] = cc*size[c[p2][0]];
if ( cc > 0 ) ls[c[p2][0]] = rs[c[p2][0]] = ms[c[p2][0]] = sum[c[p2][0]];
else { ls[c[p2][0]] = rs[c[p2][0]] = 0; ms[c[p2][0]] = cc; }
update (p2); update (p1);
}
else if ( s[1] == 'R' ){
int x, tot;
scanf ( "%d%d", &x, &tot );
int p1 = find ( rt, x );
int p2 = find ( rt, x+tot+1 );
splay ( p1, rt );
splay ( p2, c[p1][1] );
if ( tag[c[p2][0]] == 0 ){
rev[c[p2][0]] ^= 1;
swap ( c[c[p2][0]][0], c[c[p2][0]][1] );
swap ( ls[c[p2][0]], rs[c[p2][0]] );
update (p2); update (p1);
}
}
else if ( s[1] == 'G' ){
int x, tot;
scanf ( "%d%d", &x, &tot );
int p1 = find ( rt, x );
int p2 = find ( rt, x+tot+1 );
splay ( p1, rt );
splay ( p2, c[p1][1] );
printf ( "%d\n", sum[c[p2][0]] );
}
else printf ( "%d\n", ms[rt] );
}
return 0;
}