bzoj 3223 文艺平衡树 Splay 打标志

 

是NOI2003Editor的一个子任务

 

  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 }
View Code

 

posted @ 2015-02-09 21:22  idy002  阅读(223)  评论(0编辑  收藏  举报