bzoj 3223 文艺平衡树 Splay 打标志
是NOI2003Editor的一个子任务
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <cstdio> 2 #include <vector> 3 #define maxn 100010 4 using namespace std; 5 6 struct Splay { 7 int pre[maxn], son[maxn][2], siz[maxn], rev[maxn], root; 8 9 void update( int nd ) { 10 siz[nd] = siz[son[nd][0]]+siz[son[nd][1]]+1; 11 } 12 void pushdown( int nd ) { 13 if( rev[nd] ) { 14 swap( son[nd][0], son[nd][1] ); 15 if( son[nd][0] ) rev[son[nd][0]] ^= 1; 16 if( son[nd][1] ) rev[son[nd][1]] ^= 1; 17 rev[nd] = 0; 18 } 19 } 20 int build( int lf, int rg, int p ) { 21 if( lf>rg ) return 0; 22 int mid = (lf+rg)>>1; 23 pre[mid] = p; 24 rev[mid] = 0; 25 son[mid][0] = build( lf, mid-1, mid ); 26 son[mid][1] = build( mid+1, rg, mid ); 27 update( mid ); 28 return mid; 29 } 30 void init( int n ) { 31 root = build( 1, n+2, 0 ); 32 } 33 void rotate( int nd, int d ) { 34 int p = pre[nd]; 35 int s = son[nd][!d]; 36 int ss = son[s][d]; 37 38 son[nd][!d] = ss; 39 son[s][d] = nd; 40 if( p ) son[p][ nd==son[p][1] ] = s; 41 else root = s; 42 43 pre[nd] = s; 44 pre[s] = p; 45 if( ss ) pre[ss] = nd; 46 47 update( nd ); 48 update( s ); 49 } 50 void splay( int nd, int top ) { 51 while( pre[nd]!=top ) { 52 int p = pre[nd]; 53 int nl = nd==son[p][0]; 54 if( pre[p]==top ) { 55 rotate( p, nl ); 56 } else { 57 int pp = pre[p]; 58 int pl = p==son[pp][0]; 59 if( nl==pl ) { 60 rotate( pp, pl ); 61 rotate( p, nl ); 62 } else { 63 rotate( p, nl ); 64 rotate( pp, pl ); 65 } 66 } 67 68 } 69 } 70 int find( int pos ) { 71 int nd = root; 72 while(1) { 73 pushdown( nd ); 74 int ls = siz[son[nd][0]]; 75 if( pos<=ls ) { 76 nd = son[nd][0]; 77 } else if( pos>=ls+2 ) { 78 nd = son[nd][1]; 79 pos -= ls+1; 80 } else { 81 splay( nd, 0 ); 82 return nd; 83 } 84 } 85 } 86 void reverse( int lf, int rg ) { 87 int lnd = find(lf-1); 88 int rnd = find(rg+1); 89 splay( lnd, 0 ); 90 splay( rnd, lnd ); 91 rev[son[rnd][0]] ^= 1; 92 pushdown( son[rnd][0] ); 93 splay( son[rnd][0], 0 ); 94 } 95 int get( int pos ) { 96 return find(pos); 97 } 98 }; 99 100 int n, m; 101 Splay T; 102 int main() { 103 scanf( "%d%d", &n, &m ); 104 T.init( n ); 105 for( int i=1,lf,rg; i<=m; i++ ) { 106 scanf( "%d%d", &lf, &rg ); 107 T.reverse( lf+1, rg+1 ); 108 } 109 for( int i=2; i<=n+1; i++ ) 110 printf( "%d ", T.get(i)-1 ); 111 }