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 }
————————————————