zoukankan      html  css  js  c++  java
  • BZOJ 1861: [Zjoi2006]Book 书架( splay )

    splay..

    由于想偷懒 , 不想写 insert 和 delete 操作..于是用经典的 reverse 操作 + get 一段区间操作 水过去了.. 无论是 bottom , top 还是 insert , 都相当于两次 reverse

    splay 太灵活了..很多题目应该都是怎么乱搞都可以的吧.. 

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

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #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 = 80000 + 5;
    const int maxnode = maxn + 100;
     
    int seq[ maxn ];
     
    struct Node *null , *pt;
     
    struct Node {
    Node *ch[ 2 ] , *p;
    int s , v;
    bool rev;
    Node( int _v = 0 ) {
    v = _v;
    ch[ 0 ] = ch[ 1 ] = p = null;
    rev = false;
    }
    inline void setc( Node* c , int d ) {
    ch[ d ] = c;
    c -> p = this;
    }
    inline bool d() {
    return this == p -> ch[ 1 ];
    }
    inline void upd() {
    s = ch[ 0 ] -> s + ch[ 1 ] -> s + 1;
    }
    inline void Rev() {
    rev ^= 1;
    swap( ch[ 0 ] , ch[ 1 ] );
    }
    inline void relax() {
    if( rev ) {
    rev = false;
    rep( i , 2 ) if( ch[ i ] != null ) 
       ch[ i ] -> Rev();
    }
    }
    void* operator new( size_t ) {
    return pt++;
    }
    };
     
    Node NODE[ maxnode ];
    Node* root;
    Node* V[ maxn ];
     
    Node* build( int l , int r ) {
    if( l >= r ) return null;
    int m = ( l + r ) >> 1;
    Node* t = new Node( seq[ m ] );
    V[ seq[ m ] ] = t;
    t -> setc( build( l , m ) , 0 );
    t -> setc( build( m + 1 , r ) , 1 );
    t -> upd();
    return t;
    }
     
    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 )
       t -> d() != p -> 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 );
    Node* R = select( r );
    splay( L );
    splay( R , L );
    return R -> ch[ 0 ];
    }
    void init() {
    pt = NODE;
    null = new( Node );
    null -> s = 0;
    }
     
    int main() {
    freopen( "test.in" , "r" , stdin );
    init();
    int n , m;
    cin >> n >> m;
    Rep( i , n ) scanf( "%d" , seq + i );
    seq[ 0 ] = seq[ n + 1 ] = 0;
    root = build( 0 , n + 2 );
    char s[ 10 ];
    int x , t;
    while( m-- ) {
    scanf( " %s%d" , s , &x );
    if( s[ 0 ] == 'Q' ) {
    Node* t = select( x );
    printf( "%d " , t -> v );
    splay( t );
    } else if( s[ 0 ] == 'A' ) {
    Node* t = V[ x ];
    splay( t );
    printf( "%d " , t -> ch[ 0 ] -> s - 1 );
    } else if( s[ 0 ] == 'B' ) {
    Node* t = V[ x ];
    splay( t );
    int s = t -> ch[ 0 ] -> s;
    get( s , n ) -> Rev();
    get( s , n - 1 ) -> Rev();
    } else if( s[ 0 ] == 'T' ) {
    Node* t = V[ x ];
    splay( t );
    int s = t -> ch[ 0 ] -> s;
    get( 1 , s ) -> Rev();
    get( 2 , s ) -> Rev();
    } else {
    int a;
    scanf( "%d" , &a );
    Node* t = V[ x ];
    splay( t );
    int s = t -> ch[ 0 ] -> s;
    int l = s , r = s + a;
    if( l == r ) continue;
    if( l > r ) swap( l , r );
    get( l , r ) -> Rev();
    }
    }
    return 0;
    }

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

    1861: [Zjoi2006]Book 书架

    Time Limit: 4 Sec  Memory Limit: 64 MB
    Submit: 760  Solved: 437
    [Submit][Status][Discuss]

    Description

    小T有一个很大的书柜。这个书柜的构造有些独特,即书柜里的书是从上至下堆放成一列。她用1到n的正整数给每本书都编了号。 小T在看书的时候,每次取出一本书,看完后放回书柜然后再拿下一本。由于这些书太有吸引力了,所以她看完后常常会忘记原来是放在书柜的什么位置。不过小T的记忆力是非常好的,所以每次放书的时候至少能够将那本书放在拿出来时的位置附近,比如说她拿的时候这本书上面有X本书,那么放回去时这本书上面就只可能有X-1、X或X+1本书。 当然也有特殊情况,比如在看书的时候突然电话响了或者有朋友来访。这时候粗心的小T会随手把书放在书柜里所有书的最上面或者最下面,然后转身离开。 久而久之,小T的书柜里的书的顺序就会越来越乱,找到特定的编号的书就变得越来越困难。于是她想请你帮她编写一个图书管理程序,处理她看书时的一些操作,以及回答她的两个提问:(1)编号为X的书在书柜的什么位置;(2)从上到下第i本书的编号是多少。

    Input

    第一行有两个数n,m,分别表示书的个数以及命令的条数;第二行为n个正整数:第i个数表示初始时从上至下第i个位置放置的书的编号;第三行到m+2行,每行一条命令。命令有5种形式: 1. Top S——表示把编号为S的书房在最上面。 2. Bottom S——表示把编号为S的书房在最下面。 3. Insert S T——T∈{-1,0,1},若编号为S的书上面有X本书,则这条命令表示把这本书放回去后它的上面有X+T本书; 4. Ask S——询问编号为S的书的上面目前有多少本书。 5. Query S——询问从上面数起的第S本书的编号。

    Output

    对于每一条Ask或Query语句你应该输出一行,一个数,代表询问的答案。

    Sample Input

    10 10
    1 3 2 7 5 8 10 4 9 6
    Query 3
    Top 5
    Ask 6
    Bottom 3
    Ask 3
    Top 6
    Insert 4 -1
    Query 5
    Query 2
    Ask 2

    Sample Output

    2
    9
    9
    7
    5
    3

    HINT

    数据范围


    100%的数据,n,m < = 80000

     

    Source

  • 相关阅读:
    Cocos2d-x之绘制圆形
    Cocos2d-x之绘制填充矩形
    Cocos2d-x之绘制矩形
    Cocos2d-x之绘图API说明
    cocos2d-x之监听手机的物理按键
    cocos2d-x之加速度传感器
    cocos2d-x之多点触摸事件
    cocos2d-x之事件传递(onTouchBegan的返回值的作用)
    pickle
    配置文件
  • 原文地址:https://www.cnblogs.com/JSZX11556/p/4590767.html
Copyright © 2011-2022 走看看