# bzoj3223

splay的区间操作最重要的一点就是提取区间

  1 var son:array[-1..100010,1..2] of longint;
2     count,fa,a,b:array[-1..100010] of longint;
3     v:array[-1..100010] of boolean;
4     i,n,m,t,root,x,y:longint;
5
6 procedure swap(var a,b:longint);
7   var c:longint;
8   begin
9     c:=a;
10     a:=b;
11     b:=c;
12   end;
13
14 procedure change(x:longint);
15   begin
16     if x=-1 then exit;
17     swap(son[x,1],son[x,2]);
18     v[x]:=not v[x];
19   end;
20
21 procedure push(x:longint);
22   begin
23     if v[x] then
24     begin
25       change(son[x,1]);
26       change(son[x,2]);
27       v[x]:=false;
28     end;
29   end;
30
31 procedure update(x:longint);
32   begin
33     count[x]:=count[son[x,1]]+count[son[x,2]]+1;
34   end;
35
36 procedure rotate(x,w:longint);
37   var y:longint;
38   begin
39     push(x);
40     y:=fa[x];
41     if fa[y]<>-1 then
42     begin
43       if son[fa[y],1]=y then son[fa[y],1]:=x
44       else son[fa[y],2]:=x;
45     end;
46     fa[x]:=fa[y];
47     son[y,3-w]:=son[x,w];
48     if son[x,w]<>-1 then fa[son[x,w]]:=y;
49     son[x,w]:=y;
50     fa[y]:=x;
51     update(y);
52     update(x);
53   end;
54
55 procedure splay(x,f:longint);
56   var y:longint;
57   begin
58     while fa[x]<>f do
59     begin
60       y:=fa[x];
61       if fa[y]=f then
62       begin
63         if son[y,1]=x then rotate(x,2)
64         else rotate(x,1);
65       end
66       else begin
67         if son[fa[y],1]=y then
68         begin
69           if son[y,1]=x then rotate(y,2) else rotate(x,1);
70           rotate(x,2);
71         end
72         else begin
73           if son[y,1]=x then rotate(x,2) else rotate(y,1);
74           rotate(x,1);
75         end;
76       end;
77     end;
78     if f=-1 then root:=x;
79   end;
80
81 function build(l,r:longint):longint;
82   var m:longint;
83   begin
84     m:=(l+r) shr 1;
85     build:=m;
86     if l<=m-1 then
87     begin
88       son[m,1]:=build(l,m-1);
89       fa[son[m,1]]:=m;
90     end;
91     if m+1<=r then
92     begin
93       son[m,2]:=build(m+1,r);
94       fa[son[m,2]]:=m;
95     end;
96     update(m);
97   end;
98
99 function find(k:longint):longint;
100   var p:longint;
101   begin
102     p:=root;
103     while true do
104     begin
105       push(p);
106       if count[son[p,1]]+1=k then exit(p)
107       else if count[son[p,1]]+1>k then p:=son[p,1]
108       else begin
109         k:=k-count[son[p,1]]-1;
110         p:=son[p,2];
111       end;
112     end;
113   end;
114
115 procedure work(x,y:longint);
116   begin
117     x:=find(x);
118     y:=find(y+2);
119     splay(x,-1);
120     splay(y,x);
121     change(son[y,1]);
122   end;
123
124 procedure mid(x:longint);
125   begin
126     push(x);
127     if son[x,1]<>-1 then mid(son[x,1]);
128     inc(t);
129     b[t]:=a[x];
130     if son[x,2]<>-1 then mid(son[x,2]);
131   end;
132
133 begin
134   fillchar(son,sizeof(son),255);
135   fillchar(fa,sizeof(fa),255);
137   for i:=0 to n+1 do
138     a[i]:=i;
139   root:=build(0,n+1);  //先直接建立一棵平衡的BST
140   for i:=1 to m do
141   begin
149 end.