Splay(区间翻转) 模板

洛谷:P3391 【模板】文艺平衡树(Splay)

#include <algorithm>
#include <cstdio>
#include <iostream>
using namespace std;
const int MAXN = 110000;
int n, m, tp, root, CNT;
int key[MAXN], lz[MAXN], fa[MAXN], sz[MAXN], val[MAXN], q[MAXN], Q[MAXN], ch[MAXN][2];
void update( int k )
{
    sz[k] = sz[ch[k][0]] + sz[ch[k][1]] + 1;
}
void rotate( int x, int& y )
{
    int old = fa[x], oldf = fa[old], op = ch[old][1] == x;
    if ( old == y )
        y = x;
    else
        ch[oldf][ch[oldf][1] == old] = x;
    fa[x] = oldf;
    fa[ch[x][op ^ 1]] = old;
    ch[old][op] = ch[x][op ^ 1];
    fa[old] = x;
    ch[x][op ^ 1] = old;
    update( old );
    update( x );
}
void down( int x )
{
    if ( lz[x] )
    {
        lz[x] ^= 1;
        lz[ch[x][0]] ^= 1;
        lz[ch[x][1]] ^= 1;
        swap( ch[x][0], ch[x][1] );
    }
}
void splay( int x, int& y )
{
    int now = x, old, oldf;
    Q[++tp] = now;
    while ( now != y )
        Q[++tp] = fa[now], now = fa[now];
    while ( tp-- )
        down( Q[tp] );
    while ( x != y )
    {
        old = fa[x], oldf = fa[old];
        if ( old != y )
        {
            if ( ( ch[old][0] == x ) ^ ( ch[oldf][0] == old ) )
                rotate( x, y );
            else
                rotate( old, y );
        }
        rotate( x, y );
    }
}
void Build( int& k, int ll, int rr, int FA )
{
    int mid = ( ll + rr ) / 2;
    k = ++CNT;
    fa[k] = FA;
    key[k] = val[mid];
    if ( mid > ll )
        Build( ch[k][0], ll, mid - 1, k );
    if ( mid < rr )
        Build( ch[k][1], mid + 1, rr, k );
    update( k );
}
int findx( int x )  //注意下放。
{
    int now = root;
    while ( 1 )
    {
        down( now );
        if ( x <= sz[ch[now][0]] )
            now = ch[now][0];
        else
        {
            x -= sz[ch[now][0]] + 1;
            if ( x == 0 )
                return now;
            else
                now = ch[now][1];
        }
    }
}
void rev( int L, int R )
{
    int ll = findx( L - 1 ), rr = findx( R + 1 );
    splay( ll, root );
    splay( rr, ch[root][1] );
    lz[ch[ch[root][1]][0]] ^= 1;
}
void dfs( int u )
{
    down( u );
    if ( ch[u][0] )
        dfs( ch[u][0] );
    if ( key[u] != 0 && key[u] != n + 1 )
        printf( "%d ", key[u] );
    if ( ch[u][1] )
        dfs( ch[u][1] );
}
int main()
{
    scanf( "%d%d", &n, &m );
    for ( int i = 1; i <= n; i++ )
        val[i] = i;
    Build( root, 0, n + 1, 0 );
    for ( int i = 1, L, R; i <= m; i++ )
    {
        scanf( "%d%d", &L, &R );
        L++;
        R++;
        rev( L, R );
    }
    dfs( root );
    puts( "" );
    return 0;
}
posted @ 2017-12-17 20:29  D_O_Time  阅读(403)  评论(0编辑  收藏  举报