BZOJ3223 文艺平衡树

splay的区间翻转,splay(l-1,f[rot]),splay(r+1,rot);

之后将ch[ch[rot][1]][0]的子树翻转

理论简单,操作闹腾...

附上代码,splay区间操作入门题

 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <cmath>
 4 #include <cstring>
 5 #include <iostream>
 6 #include <queue>
 7 #include <cstdlib>
 8 using namespace std;
 9 #define N 100050
10 #define get(rt) (ch[f[rt]][0]!=rt)
11 #define PushUp(rt) if(rt)siz[rt]=siz[ch[rt][0]]+siz[ch[rt][1]]+1
12 int ch[N][2],f[N],siz[N],val[N];
13 int rot,n,Q;
14 bool tag[N];
15 void PushDown(int x)
16 { 
17     if(!tag[x])return ;
18     tag[x]=0;
19     swap(ch[x][0],ch[x][1]);
20     tag[ch[x][0]]^=1;
21     tag[ch[x][1]]^=1; 
22 }
23 void rotate(int rt)
24 {
25     int x=f[rt],y=f[x],b=get(rt);
26     ch[x][b]=ch[rt][b^1];f[ch[x][b]]=x;ch[rt][b^1]=x;f[x]=rt;f[rt]=y;
27     if(y)ch[y][ch[y][0]!=x]=rt;
28     PushUp(x);PushUp(rt);
29     if(rot==x)rot=rt;
30 }
31 void splay(int rt,int y)
32 {
33     for(int fa;(fa=f[rt])!=y;rotate(rt))
34     {
35         if(f[fa]!=y)
36         {
37             rotate((get(rt)==get(fa))?fa:rt);
38         }
39     }
40 }
41 int find(int x)
42 {
43     int now=rot;
44     while(1)
45     {
46         PushDown(now);
47         if(x<=siz[ch[now][0]])now=ch[now][0];
48         else
49         {
50             x-=siz[ch[now][0]]+1;
51             if(!x)return now;
52             now=ch[now][1];
53         }
54     }
55 }
56 void build(int fa,int l,int r)
57 {
58     if(l>r)return ;
59     int m=(l+r)>>1;
60     ch[fa][m>fa]=m;
61     siz[m]=1;
62     val[m]=m-1;
63     f[m]=fa;
64     build(m,l,m-1);
65     build(m,m+1,r);
66     PushUp(m);
67 }
68 void reverse(int x,int y)
69 {
70     x=find(x);
71     y=find(y);
72     splay(x,f[rot]);
73     splay(y,rot);
74     tag[ch[y][0]]^=1;
75 }
76 int main()
77 {
78     scanf("%d%d",&n,&Q);
79     build(0,1,n+2);
80     rot=(n+3)>>1;
81     for(int i=1;i<=Q;i++)
82     {
83         int x,y;
84         scanf("%d%d",&x,&y);
85         reverse(x,y+2);
86     }
87     for(int i=2;i<=n;i++)printf("%d ",val[find(i)]);
88     printf("%d\n",val[find(n+1)]);
89 }
View Code

 

posted @ 2018-04-02 13:56  Winniechen  阅读(186)  评论(0编辑  收藏  举报