题目分析:题目很简单,就维护左连续最大和,右连续最大和,以及区间最大和,区间和,是否反转,是否被置为相同即可。
一开始漏考虑了翻转的时候左右连续最大和也要翻转,还有就是区间最大和可能等于自身。。
明明很简单的题。。却调了那么久。。不说了。。
代码如下:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std ;
typedef long long LL ;
#pragma comment(linker, "/STACK:16777216")
#define Log( i , a , b ) for ( int i = a ; ( 1 << i ) <= b ; ++ i )
#define rep( i , a , b ) for ( int i = a ; i < b ; ++ i )
#define For( i , a , b ) for ( int i = a ; i <= b ; ++ i )
#define rev( i , a , b ) for ( int i = ( a ) ; i >= ( b ) ; -- i )
#define travel( e , H , u ) for ( Edge* e = H[u] ; e ; e = e -> next )
#define clr( a , x ) memset ( a , x , sizeof a )
#define cpy( a , x ) memcpy ( a , x , sizeof a )
const int MAXN = 1000005 ;
const int INF = 100000000 ;
struct Node* null ;
struct Node* root ;
struct Node {
Node* f ;
Node* c[2] ;
int v ;
int s ;
int sum ;
int Lmax ;
int Mmax ;
int Rmax ;
int flip ;
int same ;
inline int max ( const int& a , const int& b ) {
if ( a > b ) return a ;
return b ;
}
inline int max ( const int& a , const int& b , const int& c ) {
if ( a > b ) {
if ( a > c ) return a ;
return c ;
} else {
if ( b > c ) return b ;
return c ;
}
}
inline void newnode ( Node* fa , int val ) {
s = 1 ;
f = fa ;
same = flip = 0 ;
c[0] = c[1] = null ;
v = sum = Lmax = Mmax = Rmax = val ;
}
inline void link_child ( Node* o , int d ) {
c[d] = o ;
o->f = this ;
}
inline void make_flip () {
if ( this == null ) return ;
swap ( c[0] , c[1] ) ;
swap ( Lmax , Rmax ) ;
flip ^= 1 ;
}
inline void make_same ( int val ) {
if ( this == null ) return ;
v = val ;
same = 1 ;
sum = s * v ;
Lmax = Rmax = Mmax = max ( v , sum ) ;
}
void push_up () {
s = c[0]->s + 1 + c[1]->s ;
sum = c[0]->sum + v + c[1]->sum ;
Lmax = max ( c[0]->Lmax , c[0]->sum + v , c[0]->sum + v + c[1]->Lmax ) ;
Rmax = max ( c[1]->Rmax , c[1]->sum + v , c[1]->sum + v + c[0]->Rmax ) ;
Mmax = max ( v , c[0]->Mmax , c[1]->Mmax ) ;//这里忘记Mmax可能等于v了,WA死。。
Mmax = max ( Mmax , max ( c[0]->Rmax + v , c[1]->Lmax + v ) , c[0]->Rmax + v + c[1]->Lmax ) ;
}
void push_down () {
if ( flip ) {
c[0]->make_flip () ;
c[1]->make_flip () ;
flip = 0 ;
}
if ( same ) {
c[0]->make_same ( v ) ;
c[1]->make_same ( v ) ;
same = 0 ;
}
}
void sign_down () {
if ( f != null ) f->sign_down () ;
push_down () ;
}
void rotate ( int d ) {
Node* p = f ;
Node* gp = f->f ;
p->link_child ( c[d] , !d ) ;
if ( gp != null ) gp->link_child ( this , p == gp->c[1] ) ;
else f = null ;
link_child ( p , d ) ;
p->push_up () ;
}
void splay ( Node* r = null ) {
sign_down () ;
while ( f != r ) {
if ( f->f == r ) {
this == f->c[0] ? rotate ( 1 ) : rotate ( 0 ) ;
} else {
if ( f == f->f->c[0] ) {
this == f->c[0] ? f->rotate ( 1 ) : rotate ( 0 ) ;
rotate ( 1 ) ;
} else {
this == f->c[1] ? f->rotate ( 0 ) : rotate ( 1 ) ;
rotate ( 0 ) ;
}
}
}
push_up () ;
if ( r == null ) root = this ;
}
} ;
struct Splay {
Node node[MAXN] ;
Node* cur ;
Node* pool[MAXN] ;
int top ;
void push_back ( Node* o ) {
if ( o == null ) return ;
pool[top ++] = o ;
push_back ( o->c[0] ) ;
push_back ( o->c[1] ) ;
}
void select ( int kth , Node* r ) {
++ kth ;
Node* o = root ;
while ( o != null ) {
o->push_down () ;
int s = o->c[0]->s ;
if ( s + 1 == kth ) break ;
if ( kth <= s ) o = o->c[0] ;
else o = o->c[1] , kth -= s + 1 ;
}
o->splay ( r ) ;
}
Node* get ( int l , int r ) {
select ( l - 1 , null ) ;
select ( r + 1 , root ) ;
return root->c[1]->c[0] ;
}
void reverse ( int l , int r ) {
Node* o = get ( l , r ) ;
o->make_flip () ;
o->splay () ;
}
void set ( int l , int r , int val ) {
Node* o = get ( l , r ) ;
o->make_same ( val ) ;
o->splay () ;
}
void remove ( int l , int r ) {
Node* o = get ( l , r ) ;
root->c[1]->c[0] = null ;
root->c[1]->push_up () ;
root->push_up () ;
push_back ( o ) ;
}
void insert ( Node* o , int pos ) {
get ( pos + 1 , pos ) ;
root->c[1]->link_child ( o , 0 ) ;
root->c[1]->push_up () ;
root->push_up () ;
o->splay () ;
}
void query_sum ( int l , int r ) {
printf ( "%d\n" , get ( l , r )->sum ) ;
}
void query_max_sum () {
printf ( "%d\n" , root->Mmax ) ;
}
Node* make_new_tree ( int num[] , int n ) {
Node* x = null ;
Node* o = null ;
For ( i , 1 , n ) {
if ( top ) o = pool[-- top] ;
else o = cur ++ ;
o->newnode ( null , num[i] ) ;
o->link_child ( x , 0 ) ;
o->push_up () ;
x = o ;
}
return o ;
}
void clear () {
top = 0 ;
cur = node ;
null = cur ++ ;
null->newnode ( null , -INF ) ;
null->s = 0 ;
null->sum = 0 ;
root = cur ++ ;
root->newnode ( null , -INF ) ;
root->c[1] = cur ++ ;
root->c[1]->newnode ( root , -INF ) ;
root->push_up () ;
}
} S ;
int num[MAXN] ;
char op[20] ;
int n , m ;
void solve () {
int pos , tot , x ;
S.clear () ;
For ( i , 1 , n ) scanf ( "%d" , &num[i] ) ;
Node* o = S.make_new_tree ( num , n ) ;
S.insert ( o , 0 ) ;
while ( m -- ) {
scanf ( "%s" , op ) ;
if ( op[0] == 'I' ) {
scanf ( "%d%d" , &pos , &tot ) ;
For ( i , 1 , tot ) scanf ( "%d" , &num[i] ) ;
Node* o = S.make_new_tree ( num , tot ) ;
S.insert ( o , pos ) ;
} else if ( op[0] == 'D' ) {
scanf ( "%d%d" , &pos , &tot ) ;
S.remove ( pos , pos + tot - 1 ) ;
} else if ( op[2] == 'K' ) {
scanf ( "%d%d%d" , &pos , &tot , &x ) ;
S.set ( pos , pos + tot - 1 , x ) ;
} else if ( op[0] == 'R' ) {
scanf ( "%d%d" , &pos , &tot ) ;
S.reverse ( pos , pos + tot - 1 ) ;
} else if ( op[0] == 'G' ) {
scanf ( "%d%d" , &pos , &tot ) ;
S.query_sum ( pos , pos + tot - 1 ) ;
} else S.query_max_sum () ;
}
}
int main () {
while ( ~scanf ( "%d%d" , &n , &m ) ) solve () ;
return 0 ;
}