zoukankan      html  css  js  c++  java
  • BZOJ 1251: 序列终结者( splay )

    先orz一下clj...我的splay跟着他写的...

    这道题很普通的splay我调了这么久 T T , 就是因为 null 的值初始化为0 , 结果就挂了...

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

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<iostream>
     
    #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 = 50000 + 5;
    const int maxnode = maxn + 10;
    const int inf = 0x7fffffff;
     
    int n;
     
    struct Node *pt , *null;
     
    struct Node { 
    Node *ch[ 2 ] , *p;
    int val , mx , add , size;
    bool rev;
    Node() : val( 0 ) , add( 0 ) , rev( 0 ) , mx( 0 ) {
    ch[ 0 ] = ch[ 1 ] = null;
    }
    bool d() {
    return this == p -> ch[ 1 ];
    }
    void setc( Node* c , int d ) {
    ch[ d ] = c;
    c -> p = this;
    }
    void Rev() {
    rev ^= 1;
    }
    void Add( int ad ) {
    add += ad;
    val += ad;
    mx += ad;
    }
    void upd() {
    size = ch[ 0 ] -> size + ch[ 1 ] -> size + 1;
    mx = max( val , max( ch[ 0 ] -> mx , ch[ 1 ] -> mx ) );
    }
    void relax() {
    if( add ) {
    rep( i , 2 ) if( ch[ i ] != null )
       ch[ i ] -> Add( add );
    add = 0;
    }
    if( rev ) {
    swap( ch[ 0 ] , ch[ 1 ] );
    rep( i , 2 ) if( ch[ i ] != null ) 
       ch[ i ] -> Rev();
    rev = false;
    }
    }
    void* operator new( size_t ) {
    return pt++;
    }
    };
     
    Node NODE[ 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;
    }
     
    Node* select( int k ) {
    for( Node* t = root ; ; ) {
    t -> relax();
    int s = t -> ch[ 0 ] -> size;
    if( k == s ) return t;
    else if( k > s ) {
    k -= s + 1;
    t = t -> ch[ 1 ];
    } else 
       t = t -> ch[ 0 ];
    }
    }
     
    void splay( Node* t , Node* f = null ) {
    while( t -> p != f ) {
    if( t -> p -> p == f ) rot( t );
    else if( t -> d() != t -> p -> d() ) rot( t ) , rot( t );
    else rot( t -> p ) , rot( t );
    }
    t -> upd();
    }
     
    Node* &get( int l , int r ) {
    l-- , r++;
    Node* L = select( l );
    Node* R = select( r );
    splay( L );
    splay( R , L );
    return R -> ch[ 0 ];
    }
     
    // [ l , r )
    Node* build( int l , int r ) {
    if( l >= r ) 
       return null;
    int m = ( l + r ) >> 1;
    Node* t = new( Node );
    t -> setc( build( l , m ) , 0 );
    t -> setc( build( m + 1 , r ) , 1 );
    t -> upd();
    return t;
    }
     
    void init() {
    pt = NODE;
    null = new( Node );
    null -> size = 0;
    null -> val = -inf;
    null -> mx = -inf;
    root = build( 0 , n + 2 );
    root -> p = null;
    }
     
    int main() {
    freopen( "test.in" , "r" , stdin );
    freopen( "test.out" , "w" , stdout );
    int m;
    cin >> n >> m;
    init();
    while( m-- ) {
    int op , L , R;
    scanf( "%d%d%d" , &op , &L , &R );
    Node* &t = get( L , R );
    if( op == 1 ) {
    int v;
    scanf( "%d" , &v );
    t -> Add( v );
    splay( t );
    } else if( op == 2 ) {
    t -> Rev();
    splay( t );
    } else 
       printf( "%d " , t -> mx );
    }
    return 0;
    }

      

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

    1251: 序列终结者

    Time Limit: 20 Sec  Memory Limit: 162 MB
    Submit: 2735  Solved: 1086
    [Submit][Status][Discuss]

    Description

    网上有许多题,就是给定一个序列,要你支持几种操作:A、B、C、D。一看另一道题,又是一个序列 要支持几种操作:D、C、B、A。尤其是我们这里的某人,出模拟试题,居然还出了一道这样的,真是没技术含量……这样 我也出一道题,我出这一道的目的是为了让大家以后做这种题目有一个“库”可以依靠,没有什么其他的意思。这道题目 就叫序列终结者吧。 【问题描述】 给定一个长度为N的序列,每个序列的元素是一个整数(废话)。要支持以下三种操作: 1. 将[L,R]这个区间内的所有数加上V。 2. 将[L,R]这个区间翻转,比如1 2 3 4变成4 3 2 1。 3. 求[L,R]这个区间中的最大值。 最开始所有元素都是0。

    Input

    第一行两个整数N,M。M为操作个数。 以下M行,每行最多四个整数,依次为K,L,R,V。K表示是第几种操作,如果不是第1种操作则K后面只有两个数。

    Output

    对于每个第3种操作,给出正确的回答。

    Sample Input

    4 4
    1 1 3 2
    1 2 4 -1
    2 1 3
    3 2 4

    Sample Output

    2
    【数据范围】
    N<=50000,M<=100000。

    HINT

    Source

  • 相关阅读:
    MySQL权限详解
    MySql 详解
    顶级Python库
    第一次读到就震撼的句子
    Windows快捷键大全
    Pycharm超级好用的快捷键——效率之王
    Django框架
    前端入门和进阶必会
    正则表达式BREs,EREs,PREs的比较
    selenium模块基础用法详解
  • 原文地址:https://www.cnblogs.com/JSZX11556/p/4579341.html
Copyright © 2011-2022 走看看