• BZOJ 1500: [NOI2005]维修数列( splay )


    splay..... 

    ------------------------------------------------------------------------

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<queue>
     
    #define rep( i , n ) for( int i = 0 ; i < n ; ++i )
    #define clr( x , c ) memset( x , c , sizeof( x ) )
    #define Rep( i , n ) for( int i = 1 ; i <= n ; ++i )
     
    using namespace std;
     
    const int maxn = 500000;
    const int maxnode = 550000;
    const int inf = int( 1e7 );
     
    struct Node* null;
    queue< Node* > Q;
    int seq[ maxn ] , tot , pos;
     
    struct Node {
    Node *ch[ 2 ] , *p;
    int s , v , sum , mx , l_m , r_m;
    bool rev , tag;
    Node( int _v = 0 ) {
    l_m = r_m = sum = mx = v = _v;
    ch[ 0 ] = ch[ 1 ] = p = null;
    rev = tag = false;
    }
    inline void relax() {
    if( rev ) {
    rev = false;
    rep( i , 2 ) if( ch[ i ] != null )
       ch[ i ] -> Rev();
    }
    if( tag ) {
    tag = false;
    rep( i , 2 ) if( ch[ i ] != null )
       ch[ i ] -> Set( v );
    }
    }
    inline void Rev() {
    rev ^= 1;
    swap( ch[ 0 ] , ch[ 1 ] );
    swap( l_m , r_m );
    }
    inline void Set( int _v ) {
    tag = true;
    v = _v;
    sum = s * _v;
    mx = r_m = l_m = _v * ( _v > 0 ? s : 1 );
    }
    inline void upd() {
    s = ch[ 0 ] -> s + ch[ 1 ] -> s + 1;
    sum = ch[ 0 ] -> sum + ch[ 1 ] -> sum + v;
    l_m = max( ch[ 0 ] -> l_m , ch[ 0 ] -> sum + v + max( 0 , ch[ 1 ] -> l_m ) );
    r_m = max( ch[ 1 ] -> r_m , ch[ 1 ] -> sum + v + max( 0 , ch[ 0 ] -> r_m ) );
    mx = max( 0 , ch[ 0 ] -> r_m ) + v + max( 0 , ch[ 1 ] -> l_m );
    mx = max( mx , max( ch[ 0 ] -> mx , ch[ 1 ] -> mx ) );
    }
    inline void setc( Node* c , int d ) {
    ch[ d ] = c;
    c -> p = this;
    }
    inline bool d() {
    return this == p -> ch[ 1 ];
    }
    void* operator new( size_t ) {
    Node* t = Q.front();
    Q.pop();
    return t;
    }
    };
     
    Node memory[ maxnode ];
    Node* root;
     
    void rot( Node* t ) {
    Node* p = t -> p;
    p -> relax();
    t -> relax();
    int d = t -> d();
    p -> p -> setc( t , p -> d() );
    p -> setc( t -> ch[ ! d ] , d );
    t -> setc( p , ! d );
    p -> upd();
    if( p == root ) root = t;
    }
     
    void splay( Node* t , Node* f = null ) {
    for( Node* p = t -> p ; p != f ; p = t -> p ) {
    if( p -> p != f )
       p -> d() != t -> d() ? rot( t ) : rot( p );
    rot( t );
    }
    t -> upd();
    }
     
    Node* select( int k ) {
    for( Node* t = root ; ; ) {
    t -> relax();
    int s = t -> ch[ 0 ] -> s;
    if( k == s ) return t;
    if( k > s )
       k -= s + 1 , t = t ->ch[ 1 ];
    else 
       t = t -> ch[ 0 ];
    }
    }
     
    Node* &get( int l , int r ) {
    l-- , r++;
    Node *L = select( l ) , *R = select( r );
    splay( L );
    splay( R , L );
    return R -> ch[ 0 ];
    }
     
    Node* build( int l , int r ) {
    if( l >= r ) return null;
    int m = ( l + r ) >> 1;
    Node* t = new Node( seq[ m ] );
    t -> setc( build( l , m ) , 0 );
    t -> setc( build( m + 1 , r ) , 1 );
    t -> upd();
    return t;
    }
     
    void ins() {
    Node *L = select( pos ) , *R = select( pos + 1 );
    splay( L ) , splay( R , L );
    R -> setc( build( 1 , tot + 1 ) , 0 );
    R -> upd();
    L -> upd();
    }
     
    void del( Node* t ) {
    if( t == null ) return;
    rep( i , 2 ) del( t -> ch[ i ] );
    Q.push( t );
    }
     
    void init() {
    rep( i , maxnode ) Q.push( memory + i );
    null = new Node( -inf );
    null -> s = 0;
    null -> sum = 0;
    }
     
    int main() {
    // freopen( "test.in" , "r" , stdin );
    // freopen( "test.out" , "w" , stdout );
    init();
    int n , m;
    cin >> n >> m;
    Rep( i , n ) scanf( "%d" , seq + i );
    root = build( 0 , n + 2 );
    char S[ 15 ];
    while( m-- ) {
    scanf( " %s" , S );
    if( S[ 2 ] == 'X' ) {
    Node* &t = get( 1 , n );
    printf( "%d " , t -> mx );
    } else {
    scanf( "%d%d" , &pos , &tot );
    if( S[ 0 ] == 'I' ) {
    n += tot;
    Rep( i , tot ) scanf( "%d" , seq + i );
    ins();
    } else if( S[ 0 ] == 'D' ) {
    Node* &t = get( pos , pos + tot - 1 );
    n -= tot;
    del( t );
    root -> ch[ 1 ] -> setc( null , 0 );
    splay( root -> ch[ 1 ] );
    } else if( S[ 0 ] == 'R' ) {
    Node* &t = get( pos , pos + tot - 1 );
    t -> Rev();
    splay( t );
    } else if( S[ 0 ] == 'M' ) {
    Node* &t = get( pos , pos + tot - 1 );
    int v;
    scanf( "%d" , &v );
    t -> Set( v );
    splay( t );
    } else if( S[ 0 ] == 'G' ) {
    Node* &t = get( pos , pos + tot -1 );
    printf( "%d " , t -> sum );
    }
    }
    }
    return 0;
    }

    ------------------------------------------------------------------------ 

    1500: [NOI2005]维修数列

    Time Limit: 10 Sec  Memory Limit: 64 MB
    Submit: 8501  Solved: 2563
    [Submit][Status][Discuss]

    Description

    Input

    输入文件的第1行包含两个数N和M,N表示初始时数列中数的个数,M表示要进行的操作数目。第2行包含N个数字,描述初始时的数列。以下M行,每行一条命令,格式参见问题描述中的表格。

    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-SUM

    Sample Output

    -1
    10
    1
    10

    HINT

    Source

  • 相关阅读:
    前端资源分享
    Java的wait(), notify()和notifyAll()使用心得(转)
    Java 理论与实践: 处理 InterruptedException(转)
    关于线程中断的总结
    Python入门(good)
    看着自己有什么样的资源,利用好这些资源就好了。不要看着别人的资源流口水(转)
    android手机SD卡中的android_secure目录
    Android中ExpandableListView控件基本使用
    华为的面试经历
    Flex强制类型转换错误
  • 原文地址:https://www.cnblogs.com/JSZX11556/p/4590615.html
Copyright © 2020-2023  润新知