# TYVJ 1730 二逼平衡树 线段树套平衡树

View Code
  1 #include <iostream>
2 #include <cstring>
3 #include <cstdio>
4 #include <cstdlib>
5 #include <algorithm>
6
7 #define INF 100000000
8 #define N 1110000
9 #define BUG system("pause")
10
11 using namespace std;
12
13 int sz[N],fa[N],son[N][2],val[N],root[N];
14 int n,cnt,m;
15 int a[N],b[N];
16 int opt,sq,sum,suc,pre,pos;
17 int q[N],tot;
18
19 struct ST
20 {
21     int l,r;
22 }T[N<<2];
23
24 inline void prt(int x)
25 {
26     if(!x) return;
27     prt(son[x][0]);
28     printf("%d   ",val[x]);
29     prt(son[x][1]);
30 }
31
32 inline void pushup(int x)
33 {
34     if(!x) return;
35     sz[x]=sz[son[x][0]]+sz[son[x][1]]+1;
36 }
37
38 inline void link(int x,int y,int c)
39 {
40     fa[x]=y; son[y][c]=x;
41 }
42
43 void rotate(int x,int c)
44 {
45     int y=fa[x];
49     pushup(y);
50 }
51
52 void splay(int x,int g,int &rt)
53 {
54     while(fa[x]!=g)
55     {
56         int y=fa[x];
57         int cy=(son[fa[y]][1]==y),cx=(son[y][1]==x);
58         if(fa[y]==g) rotate(x,cx);
59         else
60         {
61             if(cx==cy) rotate(y,cy);
62             else rotate(x,cx);
63             rotate(x,cy);
64         }
65     }
66     pushup(x);
67     if(!g) rt=x;
68 }
69
70 inline int getnum()
71 {
72     if(tot) return q[tot--];
73     return ++cnt;
74 }
75
76 inline void newnode(int y,int &x,int sp)
77 {
78     x=getnum();
79     fa[x]=y; val[x]=sp; sz[x]=1;
80     son[x][1]=son[x][0]=0;
81 }
82
83 inline void pack(int &u,int l,int r,int f)
84 {
85     if(r<l) return;
86     int mid=(l+r)>>1;
87     newnode(f,u,a[mid]);
88     pack(son[u][0],l,mid-1,u);
89     pack(son[u][1],mid+1,r,u);
90     pushup(u);
91 }
92
93 inline void bsplay(int u,int l,int r)
94 {
95     newnode(0,root[u],-INF);
96     newnode(root[u],son[root[u]][1],INF);
97     sz[root[u]]=2;
98     pack(son[son[root[u]][1]][0],l,r,son[root[u]][1]);
99     pushup(son[son[root[u]][1]][0]); pushup(son[root[u]][1]);
100 }
101
102 inline void build(int u,int l,int r)
103 {
104     T[u].l=l; T[u].r=r;
105     if(l==r)
106     {
107         bsplay(u,l,r);
108         return;
109     }
110     int mid=(l+r)>>1;
111     build(u<<1,l,mid);
112     build(u<<1|1,mid+1,r);
113     sort(a+l,a+r+1);
114     bsplay(u,l,r);
115 }
116
118 {
119     scanf("%d%d",&n,&m);
120     for(int i=1;i<=n;i++) scanf("%d",&a[i]),b[i]=a[i];
121     build(1,1,n);
122 }
123
124 inline int find(int sp,int x)
125 {
126     while(x)
127     {
128         if(val[x]==sp) return x;
129         x=son[x][val[x]<sp];
130     }
131 }
132
133 inline int getmin(int x)
134 {
135     while(son[x][0]) x=son[x][0];
136     return x;
137 }
138
139 inline int getmax(int x)
140 {
141     while(son[x][1]) x=son[x][1];
142     return x;
143 }
144
145 inline void insert(int sp,int &rt)
146 {
147     int x=rt;
148     while(son[x][val[x]<sp]) x=son[x][val[x]<sp];
149     newnode(x,son[x][val[x]<sp],sp);
150     splay(son[x][val[x]<sp],0,rt);
151 }
152
153 inline void del(int sp,int &rt)
154 {
155     int x=find(sp,rt);
156     splay(x,0,rt);
157     int y=getmax(son[x][0]),z=getmin(son[x][1]);
158     splay(y,0,rt); splay(z,y,rt);
159     q[++tot]=son[z][0]; son[z][0]=0;
160     pushup(z); pushup(y);
161 }
162
163 inline int pred(int x,int sp)
164 {
165     int re=-INF;
166     while(x)
167     {
168         if(val[x]<sp) re=max(val[x],re);
169         x=son[x][val[x]<sp];
170     }
171     return re;
172 }
173
174 inline int succ(int x,int sp)
175 {
176     int re=INF;
177     while(x)
178     {
179         if(val[x]>sp) re=min(val[x],re);
180         x=son[x][val[x]<=sp];//!!!!!
181     }
182     return re;
183 }
184
185 inline void query(int u,int l,int r)
186 {
187     if(T[u].l>=l&&T[u].r<=r)
188     {
189         if(opt==1)
190         {
191             insert(sq,root[u]);
192             sum+=sz[son[root[u]][0]]-1;
193             del(sq,root[u]);
194         }
195         else if(opt==3)
196         {
197             del(b[pos],root[u]);
198             insert(sq,root[u]);
199         }
200         else if(opt==4)
201         {
202             pre=max(pre,pred(root[u],sq));
203         }
204         else
205         {
206             suc=min(suc,succ(root[u],sq));
207         }
208         return;
209     }
210     int mid=(T[u].l+T[u].r)>>1;
211     if(r<=mid) query(u<<1,l,r);
212     else if(l>mid) query(u<<1|1,l,r);
213     else query(u<<1,l,mid),query(u<<1|1,mid+1,r);
214     if(opt==3)
215     {
216         del(b[pos],root[u]);
217         insert(sq,root[u]);
218     }
219 }
220
221 inline void go()
222 {
223     for(int i=1,aa,bb,k;i<=m;i++)
224     {
225         scanf("%d",&opt);
226         if(opt==1)
227         {
228             scanf("%d%d%d",&aa,&bb,&sq);
229             sum=0;
230             query(1,aa,bb);
231             printf("%d\n",sum+1);
232         }
233         else if(opt==2)
234         {
235             scanf("%d%d%d",&aa,&bb,&k);
236             opt=1;
237             int l=0,r=INF,ans;
238             while(l<=r)
239             {
240                 int mid=(l+r)>>1;
241                 sum=0;
242                 sq=mid; query(1,aa,bb);
243                 if(sum+1<=k) ans=mid,l=mid+1;
244                 else r=mid-1;
245             }
246             printf("%d\n",ans);
247         }
248         else if(opt==3)
249         {
250             scanf("%d%d",&pos,&sq);
251             query(1,pos,pos);
252             b[pos]=sq;
253         }
254         else if(opt==4)
255         {
256             scanf("%d%d%d",&aa,&bb,&sq);
257             pre=-INF;
258             query(1,aa,bb);
259             printf("%d\n",pre);
260         }
261         else
262         {
263             scanf("%d%d%d",&aa,&bb,&sq);
264             suc=INF;
265             query(1,aa,bb);
266             printf("%d\n",suc);
267         }
268     }
269 }
270
271 int main()
272 {
275 }