洛谷: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;
}