## BZOJ 3223 文艺平衡树 splay

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

  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
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 {
104     build(1,n+2,0); root = (3+n)>>1;
105     rep(i,1,m){
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编辑  收藏  举报