传送门:【SPOJ】4487 Can you answer these queries VI
题目分析:好久没写splay了。。不过写起来一点也不手生,还有就是这题并不能有空段,也就是至少要一个元素,我就是坑在这点上了。其他没坑点了。
这代码我写出来的第一感觉就是:就这么长?
代码如下:
#include <cstdio> #include <cstring> #include <algorithm> using namespace std ; typedef long long LL ; #define travel( e , H , u ) for ( Edge* e = H[u] ; e ; e = e -> next ) #define rep( i , a , b ) for ( int i = ( a ) ; i < ( b ) ; ++ i ) #define rev( i , a , b ) for ( int i = ( a ) ; i >= ( b ) ; -- i ) #define FOR( i , a , b ) for ( int i = ( a ) ; i <= ( b ) ; ++ i ) #define clr( a , x ) memset ( a , x , sizeof a ) #define cpy( a , x ) memcpy ( a , x , sizeof a ) const int MAXN = 200005 ; const int INF = 0x3f3f3f3f ; struct SplayNode { int v ; int s ; int sum ; int Lmax ; int Rmax ; int maxSum ; SplayNode* f ; SplayNode* c[2] ; void clear () { v = sum = s = 0 ; Lmax = Rmax = maxSum = -INF ; } void up () { s = c[0] -> s + c[1] -> s + 1 ; sum = c[0] -> sum + v + c[1] -> sum ; Lmax = max ( c[0] -> Lmax , c[0] -> sum + v + max ( 0 , c[1] -> Lmax ) ) ; Rmax = max ( c[1] -> Rmax , c[1] -> sum + v + max ( 0 , c[0] -> Rmax ) ) ; maxSum = max ( max ( c[0] -> maxSum , c[1] -> maxSum ) , max ( 0 , c[0] -> Rmax ) + v + max ( 0 , c[1] -> Lmax ) ) ; } } Tnull , *null = &Tnull ; struct Splay { SplayNode node[MAXN] ; SplayNode* root ; SplayNode* cur ; Splay () : root ( null ) , cur ( node ) {} void clear () { null -> clear () ; root = null ; cur = node ; } SplayNode* newnode ( int v , SplayNode* f ) { cur -> v = cur -> sum = cur -> Lmax = cur -> Rmax = cur -> maxSum = v ; cur -> c[0] = cur -> c[1] = null ; cur -> s = 1 ; cur -> f = f ; return cur ++ ; } void build ( int n ) { clear () ; FOR ( i , 0 , n + 1 ) { int x = -INF ; if ( i >= 1 && i <= n ) scanf ( "%d" , &x ) ; SplayNode* o = newnode ( x , null ) ; o -> c[0] = root ; root -> f = o ; root = o ; root -> up () ; } } void rotate ( SplayNode* o , bool d ) { SplayNode* p = o -> f ; p -> c[!d] = o -> c[d] ; o -> c[d] -> f = p ; o -> f = p -> f ; if ( p -> f != null ) { if ( p == p -> f -> c[0] ) p -> f -> c[0] = o ; else p -> f -> c[1] = o ; } o -> c[d] = p ; p -> f = o ; p -> up () ; if ( root == p ) root = o ; } void splay ( SplayNode* o , SplayNode* f ) { while ( o -> f != f ) { SplayNode* p = o -> f ; if ( p -> f == f ) { if ( o == p -> c[0] ) rotate ( o , 1 ) ; else rotate ( o , 0 ) ; } else { if ( p == p -> f -> c[0] ) { if ( o == p -> c[0] ) rotate ( p , 1 ) , rotate ( o , 1 ) ; else rotate ( o , 0 ) , rotate ( o , 1 ) ; } else { if ( o == p -> c[1] ) rotate ( p , 0 ) , rotate ( o , 0 ) ; else rotate ( o , 1 ) , rotate ( o , 0 ) ; } } } o -> up () ; } void select ( int k , SplayNode* f ) { SplayNode* o = root ; ++ k ; while ( o != null ) { int s = o -> c[0] -> s ; if ( k == s + 1 ) break ; if ( k <= s ) o = o -> c[0] ; else { k -= s + 1 ; o = o -> c[1] ; } } splay ( o , f ) ; } SplayNode* get ( int l , int r ) { select ( l - 1 , null ) ; select ( r + 1 , root ) ; return root -> c[1] -> c[0] ; } void remove ( int pos ) { get ( pos , pos ) ; root -> c[1] -> c[0] = null ; root -> c[1] -> up () ; root -> up () ; } void insert ( int pos , int v ) { get ( pos , pos - 1 ) ;//between x - 1 to x SplayNode* o = newnode ( v , root -> c[1] ) ; root -> c[1] -> c[0] = o ; root -> c[1] -> up () ; root -> up () ; splay ( o , null ) ; } void replace ( int pos , int v ) { select ( pos , null ) ; root -> v = v ; root -> up () ; } int query ( int L , int R ) { SplayNode* o = get ( L , R ) ; return o -> maxSum ; } } T ; int n , q ; void solve () { char op ; int x , y ; T.build ( n ) ; scanf ( "%d" , &q ) ; while ( q -- ) { scanf ( " %c" , &op ) ; if ( op == 'I' ) { scanf ( "%d%d" , &x , &y ) ; T.insert ( x , y ) ; } else if ( op == 'D' ) { scanf ( "%d" , &x ) ; T.remove ( x ) ; } else if ( op == 'R' ) { scanf ( "%d%d" , &x , &y ) ; T.replace ( x , y ) ; } else { scanf ( "%d%d" , &x , &y ) ; printf ( "%d\n" , T.query ( x , y ) ) ; } } } int main () { while ( ~scanf ( "%d" , &n ) ) solve () ; return 0 ; }