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

没什么好说的。。被坑了。。

查询排名为k的数时,二分这个数,转化成查找w的排名。

若w这个数不存在,就先插入w,然后把w旋转到根,既可以求w的排名。

 

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];
 46     link(x,fa[y],son[fa[y]][1]==y);
 47     link(son[x][!c],y,c);
 48     link(y,x,!c);
 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 
117 inline void read()
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 {
273     read(),go();
274     return 0;
275 }

 

 

 

posted @ 2013-03-17 16:37  proverbs  阅读(1023)  评论(0编辑  收藏  举报