BZOJ 3223 文艺平衡树 splay

   在czl大神的帮助下,这splay的第一题终于搞定了,好像也不难了,是我太弱了,要加油。相信自己。也不难。

记住,翻转标记应该是bool的,不是int型的,开int会比较耗时(不过为什么结构体版的比数组快呢?是我打残了?)

  1 #include<cstdio>
  2 #include<iostream>
  3 #define rep(i,j,k) for(int i = j; i <= k; i++)
  4 #define lc c[k][0]
  5 #define rc c[k][1]
  6 using namespace std;
  7 const int maxn = 100233;
  8 
  9 int c[maxn][2], pa[maxn], s[maxn], root;
 10 bool rev[maxn];
 11 
 12 int read()
 13 {
 14     int s = 0, t = 1; char c = getchar();
 15     while( !isdigit(c) ){
 16         if( c == '-' )t = -1; c = getchar();
 17     }
 18     while( isdigit(c) ){
 19         s = s * 10 + c - '0'; c = getchar();
 20     }
 21     return s * t;
 22 }
 23 
 24 void maintain(int k)
 25 {
 26     s[k] = s[lc] + s[rc] + 1;
 27 }
 28 
 29 void build(int l,int r,int pre)
 30 {
 31     if( l > r ) return;
 32     int mid = (l+r)>>1;
 33     pa[mid] = pre;
 34     if( mid < pre ) c[pre][0] = mid;
 35     else c[pre][1] = mid;
 36     if( l < r ){
 37         build(l,mid-1,mid); build(mid+1,r,mid);
 38         maintain(mid);
 39     } else s[mid] = 1;
 40 }
 41 
 42 void pushdown(int k)
 43 {
 44     if( rev[k] ){
 45         rev[lc] ^= 1, rev[rc] ^= 1;
 46         swap(lc,rc);
 47         rev[k] ^= 1;
 48     }
 49 }
 50 
 51 void rorate(int k,int &root)
 52 {
 53     int fa = pa[k], gfa = pa[fa];
 54     int l = c[fa][1] == k, r = l ^ 1;
 55     if( fa != root ){
 56         c[gfa][c[gfa][1] == fa] = k;
 57     } else root = k; 
 58     pa[fa] = k, pa[k] = gfa, pa[c[k][r]] = fa;
 59     c[fa][l] = c[k][r]; c[k][r] = fa;
 60     maintain(fa), maintain(k);
 61 }
 62 
 63 void splay(int k,int &root)
 64 {
 65     while( k != root ){
 66         int fa = pa[k], gfa = pa[fa];
 67         if( fa != root ){
 68             if( c[fa][0] == k ^ c[gfa][0] == fa ) rorate(k,root);
 69             else rorate(fa,root);
 70         } 
 71         rorate(k,root);
 72     }
 73 }
 74 
 75 int rank(int x,int k)
 76 {
 77     if( rev[k] ) pushdown(k);
 78     if( s[lc] >= x ) return rank(x,lc);
 79     else if( s[lc] + 1 < x ) return rank(x-s[lc]-1,rc);
 80     else return k;
 81 }
 82 
 83 void rever(int l,int r)
 84 {
 85     int x = rank(l,root), y = rank(r+2,root);
 86     splay(x,root); splay(y,c[x][1]);
 87     rev[c[y][0]] ^= 1;
 88 }
 89 
 90 int times = 0;
 91 int n, m;
 92 void out(int k)
 93 {
 94     if( rev[k] ) pushdown(k);
 95     if( lc ) out(lc);
 96     if( k != n+2 && k != 1 )
 97     printf("%d ", k-1);
 98     if( rc) out(rc);
 99 }
100 
101 int main()
102 {
103     n = read(), m = read();
104     build(1,n+2,0); root = (3+n)>>1; 
105     rep(i,1,m){
106         int l = read(), r = read();
107         rever(l,r);
108     }
109     out(root);
110     cout<<endl;
111     return 0;
112 }

 

人一我十,人十我万!追逐青春的梦想,怀着自信的心,永不放弃!仿佛已看到希望,尽管还在远方

posted on 2016-01-08 13:45  83131  阅读(104)  评论(0编辑  收藏  举报

导航