• BZOJ 1552: [Cerc2007]robotic sort( splay )


    kpm大神说可以用块状链表写...但是我不会...写了个splay....

    先离散化 , 然后splay结点加个min维护最小值 , 就可以了... 

    ( ps BZOJ 3506 题意一样 , 双倍经验 ) 

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

    #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 = 100000 + 5;
    const int maxnode = 101000;
    const int inf = 0x7fffffff;
     
    int n;
     
    struct data {
    int v , pos;
    bool operator < ( const data &rhs ) const {
    return ( v < rhs.v ) || ( v == rhs.v && pos < rhs.pos );
    }
    };
     
    bool cmp( const data &a , const data &b ) {
    return a.pos < b.pos;
    }
     
    data A[ maxn ];
     
    struct Node *pt , *null;
     
    struct Node {
    Node *ch[ 2 ] , *p;
    int mn , val , size;
    bool rev;
    Node( int v = inf ) {
    mn = val = v;
    ch[ 0 ] = ch[ 1 ] = null;
    rev = 0;
    }
    inline void setc( Node* c , int d ) {
    ch[ d ] = c;
    c -> p = this;
    }
    inline bool d() {
    return this == p -> ch[ 1 ];
    }
    inline void Rev() {
    rev ^= 1;
    }
    inline void upd() {
    size = ch[ 0 ] -> size + ch[ 1 ] -> size + 1;
    mn = min( val , min( ch[ 0 ] -> mn , ch[ 1 ] -> mn ) );
    }
    inline void relax() {
    if( rev ) {
    swap( ch[ 0 ] , ch[ 1 ] );
    rep( i , 2 ) if( ch[ i ] != null )
       ch[ i ] -> Rev();
    rev = 0;
    }
    }
    void* operator new( size_t ) {
    return pt++;
    }
    };
     
    Node NODE[ maxnode ];
    Node* root;
     
    Node* build( int l , int r ) {
    if( l >= r )
       return null;
    int m = ( l + r ) >> 1;
    Node* t = new Node( A[ m ].v );
    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 ) {
    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* select( int k ) {
    for( Node* t = root ; ; ) {
    t -> relax();
    int s = t -> ch[ 0 ] -> size;
    if( s == k ) return t;
    else if( s < k ) {
    k -= s + 1;
    t = t -> ch[ 1 ];
    } else 
       t = t -> ch[ 0 ];
    }
    }
     
    int v;
    Node* find( Node* t ) {
    t -> relax();
    if( t -> val == v ) return t;
    else return find( t -> ch[ 0 ] -> mn != v ? t -> ch[ 1 ] : 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 -> size = 0;
    root = build( 0 , n + 2 );
    root -> p = null;
    }
     
    int main() {
    freopen( "test.in" , "r" , stdin );
    cin >> n;
    Rep( i , n ) {
    scanf( "%d" , &A[ i ].v );
    A[ i ].pos = i;
    }
    sort( A + 1 , A + n + 1 );
    Rep( i , n ) A[ i ].v = i;
    sort( A + 1 , A + n + 1 , cmp );
    A[ 0 ].v = A[ n + 1 ].v = inf;
    init();
    Rep( i , n ) {
    v = i;
    Node* &t = get( i , n );
    Node* x = find( t );
    splay( x );
    int k = x -> ch[ 0 ] -> size;
    printf( "%d" , k );
    if( i != n ) printf( " " );
    x = get( i , k );
    x -> Rev();
    splay( x );
    }
    return 0;
    }

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

    1552: [Cerc2007]robotic sort

    Time Limit: 5 Sec  Memory Limit: 64 MB
    Submit: 486  Solved: 203
    [Submit][Status][Discuss]

    Description

    Input

    输入共两行,第一行为一个整数N,N表示物品的个数,1<=N<=100000。第二行为N个用空格隔开的正整数,表示N个物品最初排列的编号。

    Output

    输出共一行,N个用空格隔开的正整数P1,P2,P3…Pn,(1 < = Pi < = N),Pi表示第i次操作前第i小的物品所在的位置。 注意:如果第i次操作前,第i小的物品己经在正确的位置Pi上,我们将区间[Pi,Pi]反转(单个物品)。

    Sample Input

    6
    3 4 5 1 6 2

    Sample Output

    4 6 4 5 6 6

    HINT

    Source

  • 相关阅读:
    RFID亮灯电子标签在仓储管理中的应用
    漫画:寻找股票买入卖出的最佳时机(动态规划)
    JAVA深入解析-36个话题-Two
    一行代码让训练速度提升2倍,飞桨自动混合精度技术详解
    追源码的平凡之路
    看完这篇,你也是字符编码大神!
    微服务的熔断原理与实现
    经典论文复现 | PyraNet:基于特征金字塔网络的人体姿态估计
    一文看懂人机对话
    「Spring Boot 2.4 新特性」一键构建Docker镜像
  • 原文地址:https://www.cnblogs.com/JSZX11556/p/4580739.html
Copyright © 2020-2023  润新知