zoukankan      html  css  js  c++  java
  • BZOJ 3196: Tyvj 1730 二逼平衡树( 树套树 )

    这道题做法应该很多吧....

    我用了线段树套treap.... 

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

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cstdlib>
    #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 )
    #define M( l , r ) ( ( ( l ) + ( r ) ) >> 1 )
     
    using namespace std;
     
    const int maxn = 50000 + 5;
    const int maxnode = 1500000;
    const int inf = 1e9;
    const unsigned int A = 654321 , B = 54321;
     
    int seq[ maxn ] , mn , mx , n;
    unsigned int P = 820;
     
    // treap node
    struct Node {
    Node* ch[ 2 ];
    int s , v;
    unsigned int r;
    Node() : s( 0 ) { }
    inline void upd() {
    s = ch[ 0 ] -> s + ch[ 1 ] -> s + 1;
    }
    } pool[ maxnode ] , *pt = pool , *null = pt++;
     
    Node* newNode( int v = 0 ) {
    pt -> v = v;
    ( P *= A ) += B;
    pt -> r = P;
    pt -> s = 1;
    pt -> ch[ 0 ] = pt -> ch[ 1 ] = null;
    return pt++;
    }
     
    struct treap {
    Node* root;
    treap() {
    root = null;
    }
    void rot( Node* &t , int d ) {
    Node* k = t -> ch[ d ^ 1 ];
    t -> ch[ d ^ 1 ] = k -> ch[ d ];
    k -> ch[ d ] = t;
    t -> upd() , k -> upd();
    t = k;
    }
    void ins( Node* &t , int v ) {
    if( t == null )
    t = newNode( v );
    else {
    int d = v > t -> v;
    ins( t -> ch[ d ] , v );
    if( t -> ch[ d ] -> r > t -> r )
       rot( t , d ^ 1 );
    }
    t -> upd();
    }
    void del( Node* &t , int v ) {
    int d = t -> v == v ? -1 : ( t -> v < v );
    if( d == -1 ) {
    if( t -> ch[ 0 ] != null & t -> ch[ 1 ] != null ) {
    int h = t -> ch[ 0 ] -> r > t -> ch[ 1 ] -> r;
    rot( t , h ) , del( t -> ch[ h ] , v );
    } else
       t = t -> ch[ 0 ] == null ? t -> ch[ 1 ] : t -> ch[ 0 ];
    } else 
       del( t -> ch[ d ] , v );
    if( t != null ) t -> upd();
    }
    int select( int k ) {
    for( Node* t = root ; ; ) {
    int s = t -> ch[ 0 ] -> s + 1;
    if( k == s + 1 ) return t -> v;
    if( k < s )
       t = t -> ch[ 0 ];
    else
       k -= s + 1 , t = t -> ch[ 1 ];
    }
    }
    int rank( int v ) {
    int ans = 0;
    for( Node* t = root ; t != null ; ) {
    if( t -> v < v )
       ans += t -> ch[ 0 ] -> s + 1 , t = t -> ch[ 1 ];
    else 
       t = t -> ch[ 0 ];
    }
    return ans;
    }
    int pred( int v ) {
    int ans = -inf;
    for( Node* t = root ; t != null ; ) {
    if( t -> v < v )
       ans = max( ans , t -> v ) , t = t -> ch[ 1 ];
    else
       t = t -> ch[ 0 ];
    }
    return ans;
    }
    int succ( int v ) {
    int ans = inf;
    for( Node* t = root ; t != null ; ) {
    if( t -> v > v )
       ans = min( t -> v , ans ) , t = t -> ch[ 0 ];
    else 
       t = t -> ch[ 1 ];
    }
    return ans;
    }
    } TREAP[ maxn << 1 ] , *pit = TREAP;
     
    // segment tree node
    struct node {
    node *l , *r;
    treap* x;
    } mem[ maxn << 1 ] , *pT = mem , *Rt;
     
    int L , R , v;
     
    void build( node* t , int l , int r ) {
    t -> x = pit++;
    for( int i = l ; i <= r ; i++ )
       t -> x -> ins( t -> x -> root , seq[ i ] );
    if( r > l ) {
    int m = M( l , r );
    build( t -> l = pT++ , l , m );
    build( t -> r = pT++ , m + 1 , r );
    }
    }
     
    void change( node* t , int l , int r ) {
    if( r < L || l > L ) return;
    t -> x -> del( t -> x -> root , seq[ L ] );
    t -> x -> ins( t -> x -> root , v );
    if( l == r ) return;
    int m = M( l , r );
    L <= m ? change( t -> l , l , m ) : change( t -> r , m + 1 , r );
    }
     
    int rank( node* t , int l , int r ) {
    if( L <= l && r <= R ) 
       return t -> x -> rank( v );
    int m = M( l , r );
    return ( L <= m ? rank( t -> l , l , m ) : 0 ) +
          ( m < R ? rank( t -> r , m + 1 , r ) : 0 );
    }
     
    int pred( node* t , int l , int r ) {
    if( L <= l && r <= R ) 
       return t -> x -> pred( v );
    int m = M( l , r );
    if( R <= m ) return pred( t -> l , l , m );
    else if( L > m ) return pred( t -> r , m + 1 , r );
    else return max( pred( t -> l , l , m ) , pred( t -> r , m + 1 , r ) );
    }
     
    int succ( node* t , int l , int r ) {
    if( L <= l && r <= R ) 
       return t -> x -> succ( v );
    int m = M( l , r );
    if( R <= m ) return succ( t -> l , l , m );
    else if( L > m ) return succ( t -> r , m + 1 , r );
    else return min( succ( t -> l , l , m ) , succ( t -> r , m + 1 , r ) );
    }
     
    int select( int k ) {
    int l = mn , r = mx , ans;
    while( l <= r ) {
    v = M( l , r );
    int h = rank( Rt , 1 , n );
    if( rank( Rt , 1 , n ) < k )
       ans = v , l = v + 1;
    else
       r = v - 1;
    }
    return ans;
    }
     
    inline void read( int &x ) {
    x = 0;
    int sign = 1;
    char c = getchar();
    for( ; ! isdigit( c ) ; c = getchar() )
       if( c == '-' ) sign = -1;
    for( ; isdigit( c ) ; c = getchar() )
       x = x * 10 + c - '0';
    x *= sign;
    }
     
    int main() {
    // freopen( "test.in" , "r" , stdin );
    int m;
    cin >> n >> m;
    Rep( i , n ) {
       read( seq[ i ] );
       mn = i == 1 ? seq[ i ] : min( seq[ i ] , mn );
       mx = i == 1 ? seq[ i ] : max( seq[ i ] , mx );
    }
    build( Rt = pT++ , 1 , n );
    int opt;
    while( m-- ) {
    read( opt ) , read( L );
    switch( opt ) {
    case 1 : read( R ); read( v ); printf( "%d " , rank( Rt , 1 , n ) + 1 ); break;
    case 2 : read( R ); read( v ); printf( "%d " , select( v ) ); break;
    case 3 : read( v ); change( Rt , 1 , n ); seq[ L ] = v; mn = min( v , mn ); mx = max( mx , v ); break;
    case 4 : read( R ); read( v ); printf( "%d " , pred( Rt , 1 , n ) ); break;
    case 5 : read( R ); read( v ); printf( "%d " , succ( Rt , 1 , n ) ); break;
    }
    }
    return 0;
    }

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

    3196: Tyvj 1730 二逼平衡树

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 1324  Solved: 562
    [Submit][Status][Discuss]

    Description

    您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:
    1.查询k在区间内的排名
    2.查询区间内排名为k的值
    3.修改某一位值上的数值
    4.查询k在区间内的前驱(前驱定义为小于x,且最大的数)
    5.查询k在区间内的后继(后继定义为大于x,且最小的数)

    Input

    第一行两个数 n,m 表示长度为n的有序序列和m个操作
    第二行有n个数,表示有序序列
    下面有m行,opt表示操作标号
    若opt=1 则为操作1,之后有三个数l,r,k 表示查询k在区间[l,r]的排名
    若opt=2 则为操作2,之后有三个数l,r,k 表示查询区间[l,r]内排名为k的数
    若opt=3 则为操作3,之后有两个数pos,k 表示将pos位置的数修改为k
    若opt=4 则为操作4,之后有三个数l,r,k 表示查询区间[l,r]内k的前驱
    若opt=5 则为操作5,之后有三个数l,r,k 表示查询区间[l,r]内k的后继

    Output

    对于操作1,2,4,5各输出一行,表示查询结果

    Sample Input

    9 6
    4 2 2 1 9 4 0 1 1
    2 1 4 3
    3 4 10
    2 1 4 3
    1 2 5 9
    4 3 9 5
    5 2 8 5

    Sample Output

    2
    4
    3
    4
    9

    HINT

    1.n和m的数据范围:n,m<=50000


    2.序列中每个数的数据范围:[0,1e8]


    3.虽然原题没有,但事实上5操作的k可能为负数

    Source

  • 相关阅读:
    数据结构-顺序表
    数据结构-概论
    社交网络图中结点的“重要性”计算 (30 分) C++解法
    面向对象程序设计--Java语言第二周编程题:有秒计时的数字时钟
    面向对象程序设计--Java语言第三周编程题:查找里程
    面向对象程序设计--Java语言第一周编程题:分数
    剑指Offer_#42_连续子数组的最大和
    vue--模态框背景不动解决方案
    redis(十七):Redis 安装,部署(WINDOWS环境下)
    redis(二十一):Redis 架构模式实现(哨兵)
  • 原文地址:https://www.cnblogs.com/JSZX11556/p/4641074.html
Copyright © 2011-2022 走看看