BZOJ-3224 普通平衡树 TYVJ-1728 Treap + Vector

来源:互联网 发布:isis软件使用方法 编辑:程序博客网 时间:2024/05/16 15:19

大家都很强, 可与之共勉。

Vector 暴力出奇迹

/**************************************************************    Problem: 3224    User: Lazer2001    Language: C++    Result: Accepted    Time:1776 ms    Memory:1212 kb****************************************************************/#include <cctype>#include <cstdio>#include <vector>#include <algorithm>std :: vector<int> vc;inline void insert( int x ) {    vc.insert( std :: lower_bound( vc.begin( ), vc.end( ), x ), x  );}inline void erase( int x ) {    vc.erase( std :: lower_bound( vc.begin( ), vc.end(), x ) );}inline int rank( int x ) {    return std :: lower_bound( vc.begin(), vc.end(), x ) - vc.begin( ) + 1;}inline int nth( int n ) {    return vc[n - 1];}inline int prev( int x ) {    return *--std :: lower_bound( vc.begin( ), vc.end( ), x );}inline int next( int x ) {    return *std :: upper_bound( vc.begin( ), vc.end( ), x );}template < class T >inline short readIn ( T& x )  {    static char ch;    static short opt;    opt = (ch != 45);    while ( !isdigit ( ch = getchar () ) && (ch ^ -1) && ( ch ^ 45 ) );    if ( ch == -1 )     return 0;    if ( ch == 45 )     {   opt = 0; ch = getchar ();   }    for ( x = -48 + ch; isdigit ( ch = getchar () ); ( x *= 10 ) += ch - 48 );    opt ? 1 : x = -x;    return 1;}template < class T >inline void writeIn ( T x )  {    static unsigned int top, t[25];    if ( !x )  {    putchar ( 48 );  return;    }    if ( x < 0 )  {      x = -x;  putchar ( 45 );    }    while ( x )     t[ ++top ] = x % 10, x /= 10;    while ( top )   putchar ( t[top--] + 48 );}int main() {    int n, opt, x;    scanf( "%d", &n );    while( n-- ) {        readIn ( opt );        readIn ( x );        switch( opt ) {            case 1:                insert( x );  break;            case 2:                erase(x);  break;            case 3:                writeIn( rank(x) ); putchar ( 10 ); break;            case 4:                writeIn( nth(x) ); putchar ( 10 ); break;            case 5:                writeIn( prev(x) ); putchar ( 10 ); break;            case 6:                writeIn( next(x) ); putchar ( 10 ); break;        }    }}

Treap RE了
占坑先, 之后填

#include <ctime>#include <cctype>#include <cstdio>template < class T > inline T max ( T a, T b )  {   return (a) > (b) ? (a) : (b);   }template < class T > inline T min ( T a, T b )  {   return (a) < (b) ? (a) : (b);   }template < class T >inline short readIn ( T& x )  {    static char ch;    static short opt;    opt = (ch != 45);    while ( !isdigit ( ch = getchar () ) && (ch ^ -1) && ( ch ^ 45 ) );    if ( ch == -1 )     return 0;    if ( ch == 45 )     {   opt = 0; ch = getchar ();   }    for ( x = -48 + ch; isdigit ( ch = getchar () ); ( x *= 10 ) += ch - 48 );    opt ? 1 : x = -x;    return 1;}template < class T >inline void writeIn ( T x )  {    static unsigned int top, t[25];    if ( !x )  {    putchar ( 48 );  return;    }    if ( x < 0 )  {     x = -x;  putchar ( 45 );    }    while ( x )     t[ ++top ] = x % 10, x /= 10;    while ( top )   putchar ( t[top--] + 48 );}inline int rand ( )  {    static int seed = 233;    return seed = ( int ) seed * 482711LL % 2147483647; }int n, x, opt;typedef class TreapNode  {public:    int val, key, siz, w;    TreapNode *ls, *rs;    TreapNode ( )  {    }    TreapNode ( int val ) : val ( val ), key ( rand ( ) ), siz ( 1 ), w ( 1 )  {  ls = rs = 0; }    } Treap;Treap pool[1000005], *root, * tail, *tmp;inline int size ( Treap* &nd )  {    return nd ? nd -> siz : 0;}inline void Zig ( Treap* &nd )  {    tmp = nd -> ls;    nd -> ls = tmp -> rs;    tmp -> rs = nd;    tmp -> siz = nd -> siz;    nd -> siz = size ( nd -> ls ) + size ( nd -> rs ) + 1;    nd = tmp;}inline void Zag ( Treap* &nd )  {    tmp = nd -> rs;    nd -> rs = tmp -> ls;    tmp -> ls = nd;    tmp -> siz = nd -> siz;    nd -> siz = size ( nd -> ls ) + size ( nd -> rs ) + 1;    nd = tmp;}inline void Insert ( Treap* &nd, int val )  {    if ( !nd )  {        nd = ++tail;        *nd = Treap ( val );        return;    }    if ( nd -> val ^ val )  {        if ( val > nd -> val )  {            Insert ( nd -> rs, val );            if ( nd -> rs -> key > nd -> key )                Zag ( nd );        }  else  {            Insert ( nd -> ls, val );            if ( nd -> ls -> key > nd -> key )                Zig ( nd );        }    }}inline int kth ( Treap* &nd, int k )  {    int tmp = size ( nd -> ls ) + 1;    if ( tmp == k )  return nd -> val;    return tmp > k ? kth ( nd -> ls, k ) : kth ( nd -> rs, k - tmp );}inline void Delete ( Treap* &nd, int x )  {    if ( !nd )  return;    if ( nd -> val == x )  {        if ( nd -> w > 1 )  {            --nd -> w, --nd -> siz; return;        }        if ( !nd -> ls && !nd -> rs )  {    nd = 0; return;   }        if ( !nd -> ls && nd -> rs )  { nd = nd -> ls; return;  }        if ( nd -> ls && !nd -> rs )  { nd = nd -> rs; return;  }        if ( nd -> ls -> key < nd -> rs -> key )  { Zig ( nd ); Delete ( nd, x );  }        else  { Zag ( nd ); Delete ( nd, x );  }    }  else if ( x > nd -> val )  {  --nd -> siz;  Delete ( nd -> rs, x ); }            else  {  --nd -> siz;  Delete ( nd -> ls, x ); }}inline int query_rank ( Treap* &nd, int x )  {    if ( !nd )  return 0;    if ( nd -> val == x )  return size ( nd -> ls ) + 1;    else  return  ( x > nd -> val ) ? size ( nd -> ls ) + nd -> w + query_rank ( nd -> rs, x )                                    : query_rank ( nd -> ls, x );}inline int query_pre ( Treap* &nd, int val )  {    if ( !nd )  return 0xefefefef;    if ( val < nd -> val )        return query_pre ( nd -> ls, val );    return max ( nd -> val, query_pre ( nd -> rs, val ) );}inline int query_post ( Treap* &nd, int val )  {    if ( !nd )  return 0x7fffffff;    if ( val > nd -> val )        return query_post ( nd -> rs, val );    return min ( nd -> val, query_post ( nd -> ls, val ) );}int main ( )  {    freopen ( "in.txt", "r", &_iob[0] );    freopen ( "out.txt", "w", &_iob[1] );    register int i;    readIn ( n );    root = 0;    tail = pool;    while ( n-- )  {        readIn ( opt );        readIn ( x );        switch( opt ) {            case 1:                Insert ( root, x );  break;            case 2:                Delete ( root, x );  break;            case 3:                writeIn( query_rank( root, x ) ); putchar ( 10 ); break;            case 4:                writeIn( kth ( root, x ) ); putchar ( 10 ); break;            case 5:                writeIn( query_pre ( root, x ) ); putchar ( 10 ); break;            case 6:                writeIn( query_post ( root, x ) ); putchar ( 10 ); break;        }    }}

我来填坑了
因为是用指针, 很多细节需要注意。
事实证明, 自己建一个null比用NULL快。
错在前后驱定义的理解。

/**************************************************************    Problem: 3224    User: Lazer2001    Language: C++    Result: Accepted    Time:340 ms    Memory:3168 kb****************************************************************/#include <cctype>#include <cstdio>template < class T >inline short readIn ( T& x )  {    static char ch;    static short opt;    opt = (ch != 45);    while ( !isdigit ( ch = getchar () ) && (ch ^ -1) && ( ch ^ 45 ) );    if ( ch == -1 )     return 0;    if ( ch == 45 )     {   opt = 0; ch = getchar ();   }    for ( x = -48 + ch; isdigit ( ch = getchar () ); ( x *= 10 ) += ch - 48 );    opt ? 1 : x = -x;    return 1;}template < class T >inline void writeIn ( T x )  {    static unsigned int top, t[25];    if ( !x )  {    putchar ( 48 );  return;    }    if ( x < 0 )  {     x = -x;  putchar ( 45 );    }    while ( x )     t[ ++top ] = x % 10, x /= 10;    while ( top )   putchar ( t[top--] + 48 );}inline int rand ( )  {    static int seed = 233;    return seed = ( int ) seed * 482711LL % 2147483647; }typedef class TreapNode  {public:    int val, key, siz, same;    TreapNode *ls, *rs;    TreapNode ( )  {    }    TreapNode ( int val, TreapNode* &node ) : val ( val ), key ( rand ( ) ), siz ( 1 ), same ( 1 )  {  ls = rs = node; } // siz = 1;     inline void update ( )  {        siz = ls -> siz + rs -> siz + same;    } } Treap;int n, x, ans, opt;Treap pool[100005], *root, * tail, *tmp, *null;inline void Zig ( Treap* &nd )  {    tmp = nd -> ls;    if ( tmp == null )  return;    nd -> ls = tmp -> rs;    tmp -> rs = nd;    tmp -> siz = nd -> siz;    nd -> update ( );    nd = tmp;}inline void Zag ( Treap* &nd )  {    tmp = nd -> rs;    if ( tmp == null )  return;    nd -> rs = tmp -> ls;    tmp -> ls = nd;    tmp -> siz = nd -> siz;    nd -> update ( );    nd = tmp;}void Insert ( Treap* &nd, int val )  {    if ( nd == null )  {        nd = ++tail;        *nd = Treap ( val, null );        return;    }       if ( nd -> val ^ val )  {        if ( val > nd -> val )  {            Insert ( nd -> rs, val );            if ( nd -> rs -> key < nd -> key )                Zag ( nd );        }  else  {            Insert ( nd -> ls, val );            if ( nd -> ls -> key < nd -> key )                Zig ( nd );        }    }  else  ++nd -> same;    nd -> update ( );}inline int kth ( Treap* &nd, int k )  {    int tmp = nd -> ls -> siz + nd -> same;    if ( nd -> ls -> siz < k && k <= tmp )  return nd -> val;    return nd -> ls -> siz >= k ? kth ( nd -> ls, k ) : kth ( nd -> rs, k - tmp );}inline void Delete ( Treap* &nd, int x )  {    if ( nd == null )  return;    if ( nd -> val == x )  {        if ( nd -> same > 1 )  {            --nd -> same; nd -> update ( ); return;        }        if ( nd -> ls == null && nd -> rs == null ) { nd = null; return;  }        else if ( nd -> ls == null && nd -> rs )  nd = nd -> rs;        else if ( nd -> ls && nd -> rs == null )  nd = nd -> ls;        if ( nd -> ls -> key < nd -> rs -> key ) { Zig ( nd ); Delete ( nd -> rs, x );  }        else  { Zag ( nd ); Delete ( nd -> ls, x );  }    }  else if ( x > nd -> val )  Delete ( nd -> rs, x );            else  Delete ( nd -> ls, x );    nd -> update ( );}inline int query_rank ( Treap* &nd, int x )  {    if ( nd == null )  return 0;    if ( nd -> val == x )  return nd -> ls -> siz + 1;    else  return  ( x > nd -> val ) ?  nd -> ls -> siz + nd -> same + query_rank ( nd -> rs, x )                                    : query_rank ( nd -> ls, x );}inline void query_pre ( Treap* &nd, int &ans, int val )  {    if ( nd == null )  return;    if ( val > nd -> val )        ans = nd -> val, query_pre ( nd -> rs, ans, val );    else query_pre ( nd -> ls, ans, val );}inline void query_post ( Treap* &nd, int &ans, int val )  {    if ( nd == null )  return;    if ( val < nd -> val )        ans = nd -> val, query_post ( nd -> ls, ans, val );    else query_post ( nd -> rs, ans, val );}int main ( )  {    readIn ( n );    tail = pool;    null = ++tail;    null -> ls = null -> rs = null;    null -> same = null -> siz = 0;    root = null;    while ( n-- )  {        readIn ( opt );        readIn ( x );        switch ( opt )  {            case 1:                Insert ( root, x );  break;            case 2:                Delete ( root, x );  break;            case 3:                writeIn( query_rank( root, x ) ); putchar ( 10 ); break;            case 4:                writeIn( kth ( root, x ) ); putchar ( 10 ); break;            case 5:                query_pre ( root, ans, x ); writeIn( ans ); putchar ( 10 ); break;            case 6:                query_post ( root, ans, x ); writeIn( ans ); putchar ( 10 ); break;        }    }}

更新Treap 208ms
FastIO里面用&_iob[]会报错, 建议用stdin, stdout.

/**************************************************************    Problem: 3224    User: Lazer2001    Language: C++    Result: Accepted    Time:208 ms    Memory:3300 kb****************************************************************/#include <cctype>#include <cstdio>namespace FastIO  {    const size_t str = 1 << 16;    struct Reader  {        char buf[str], *s, *t;        Reader ( ) : s( ), t( ), buf() {    }        inline char pick ( )  {            return (s == t) ? ( t = buf + fread ( s = buf, 1, str , stdin ), *s++ ) : ( *s++ );        }        template < class T >        inline Reader& operator >> ( T& x )  {            static char ch;            static short opt;            opt = (ch != 45);            while ( !isdigit ( ch = pick () ) && (ch ^ -1) && ( ch ^ 45 ) );            if ( ch == -1 )     return *this;            if ( ch == 45 )     {   opt = 0; ch = pick ();   }            for ( x = -48 + ch; isdigit ( ch = pick () ); ( x *= 10 ) += ch - 48 );            opt ? 1 : x = -x;            return *this;        }    } cin;    struct Writer  {        char buf[str], *s, *t;        Writer () : s ( buf ), t( buf + str ), buf ( ) {    }        ~Writer () { fwrite( buf, 1, s - buf, stdout ); }        inline void echo ( char c )  {            ( s == t ) ? ( fwrite ( s = buf, 1, str, stdout ), *s++ = c ) : ( *s++ = c );        }        inline Writer& operator << ( long long x )  {            if( !x ) return echo( 48 ), *this;            static int t[21], top;            while ( x ) t[++top] = x % 10, x /= 10;            while ( top ) echo(t[top--] + 48);            return *this;        }        inline Writer& operator << (const char* s)  {            while ( *s ) echo( *s++ ) ;            return *this;        }    } cout;    const char *endl = "\n";}using FastIO :: cin;using FastIO :: cout;using FastIO :: endl;inline int rand ( )  {    static int seed = 233;    return seed = ( int ) seed * 482711LL % 2147483647; }typedef class TreapNode  {public:    int val, key, siz, same;    TreapNode *ls, *rs;    TreapNode ( )  {    }    TreapNode ( int val, TreapNode* &node ) : val ( val ), key ( rand ( ) ), siz ( 1 ), same ( 1 )  {  ls = rs = node; } // siz = 1;     inline void update ( )  {        siz = ls -> siz + rs -> siz + same;    } } Treap;int n, x, ans, opt;Treap pool[100005], *root, * tail, *tmp, *null;inline void Zig ( Treap* &nd )  {    tmp = nd -> ls;    if ( tmp == null )  return;    nd -> ls = tmp -> rs;    tmp -> rs = nd;    tmp -> siz = nd -> siz;    nd -> update ( );    nd = tmp;}inline void Zag ( Treap* &nd )  {    tmp = nd -> rs;    if ( tmp == null )  return;    nd -> rs = tmp -> ls;    tmp -> ls = nd;    tmp -> siz = nd -> siz;    nd -> update ( );    nd = tmp;}inline void Insert ( Treap* &nd, int val )  {    if ( nd == null )  {        nd = ++tail;        *nd = Treap ( val, null );        return;    }       if ( nd -> val ^ val )  {        if ( val > nd -> val )  {            Insert ( nd -> rs, val );            if ( nd -> rs -> key < nd -> key )                Zag ( nd );        }  else  {            Insert ( nd -> ls, val );            if ( nd -> ls -> key < nd -> key )                Zig ( nd );        }    }  else  ++nd -> same;    nd -> update ( );}inline int kth ( Treap* &nd, int k )  {    int tmp = nd -> ls -> siz + nd -> same;    if ( nd -> ls -> siz < k && k <= tmp )  return nd -> val;    return nd -> ls -> siz >= k ? kth ( nd -> ls, k ) : kth ( nd -> rs, k - tmp );}inline void Delete ( Treap* &nd, int x )  {    if ( nd == null )  return;    if ( nd -> val == x )  {        if ( nd -> same > 1 )  {            --nd -> same; nd -> update ( ); return;        }        if ( nd -> ls == null && nd -> rs == null ) { nd = null; return;  }        else if ( nd -> ls == null && nd -> rs )  nd = nd -> rs;        else if ( nd -> ls && nd -> rs == null )  nd = nd -> ls;        if ( nd -> ls -> key < nd -> rs -> key ) { Zig ( nd ); Delete ( nd -> rs, x );  }        else  { Zag ( nd ); Delete ( nd -> ls, x );  }    }  else if ( x > nd -> val )  Delete ( nd -> rs, x );            else  Delete ( nd -> ls, x );    nd -> update ( );}inline int query_rank ( Treap* &nd, int x )  {    if ( nd == null )  return 0;    if ( nd -> val == x )  return nd -> ls -> siz + 1;    else  return  ( x > nd -> val ) ? nd -> ls -> siz + nd -> same + query_rank ( nd -> rs, x )                                    : query_rank ( nd -> ls, x );}inline void query_pre ( Treap* &nd, int &ans, int val )  {    if ( nd == null )  return;    if ( val > nd -> val )        ans = nd -> val, query_pre ( nd -> rs, ans, val );    else query_pre ( nd -> ls, ans, val );}inline void query_post ( Treap* &nd, int &ans, int val )  {    if ( nd == null )  return;    if ( val < nd -> val )        ans = nd -> val, query_post ( nd -> ls, ans, val );    else query_post ( nd -> rs, ans, val );}int main ( )  {    cin >> n;    tail = pool;    null = ++tail;    null -> ls = null -> rs = null;    null -> same = null -> siz = 0;    root = null;     while ( n-- )  {        cin >> opt >> x;        switch ( opt )  {            case 1:                Insert ( root, x );  break;            case 2:                Delete ( root, x );  break;            case 3:                cout << query_rank( root, x ) << endl; break;            case 4:                cout << kth ( root, x ) << endl; break;            case 5:                query_pre ( root, ans, x ); cout << ans << endl; break;            case 6:                query_post ( root, ans, x ); cout << ans << endl; break;        }    }}