BZOJ 3196: Tyvj 1730 二逼平衡树

3196: Tyvj 1730 二逼平衡树

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 3033  Solved: 1201
[Submit][Status][Discuss]

Description

您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:
1.查询k在区间内的排名
2.查询区间内排名为k的值
3.修改某一位值上的数值
4.查询k在区间内的前驱(前驱定义为小于x,且最大的数)
5.查询k在区间内的后继(后继定义为大于x,且最小的数)

Input

第一行两个数 n,m 表示长度为n的有序序列和m个操作
第二行有n个数,表示有序序列
下面有m行,opt表示操作标号
若opt=1 则为操作1,之后有三个数l,r,k 表示查询k在区间[l,r]的排名
若opt=2 则为操作2,之后有三个数l,r,k 表示查询区间[l,r]内排名为k的数
若opt=3 则为操作3,之后有两个数pos,k 表示将pos位置的数修改为k
若opt=4 则为操作4,之后有三个数l,r,k 表示查询区间[l,r]内k的前驱
若opt=5 则为操作5,之后有三个数l,r,k 表示查询区间[l,r]内k的后继

Output

对于操作1,2,4,5各输出一行,表示查询结果

Sample Input

9 6
4 2 2 1 9 4 0 1 1
2 1 4 3
3 4 10
2 1 4 3
1 2 5 9
4 3 9 5
5 2 8 5

Sample Output

2
4
3
4
9

HINT

 

1.n和m的数据范围:n,m<=50000


2.序列中每个数的数据范围:[0,1e8]


3.虽然原题没有,但事实上5操作的k可能为负数

 

Source

分析:

线段树套平衡树...

对于2操作就可以二分那个数字是区间第k大,然后查询当前数字再区间中的排名,不需要判断这个数字是否存在于区间中是因为所有排名合法的数字中最大的那个一定是答案...

比较忧伤的是写了线段树套Splay才知道我的线段树和Splay的常数有多大QAQ...

哎,没办法人帅自带大常数^_~...

  1 #include<algorithm>
  2 #include<iostream>
  3 #include<cstring>
  4 #include<cstdio>
  5 //by NeighThorn
  6 #define inf 1e8+8
  7 using namespace std;
  8 
  9 const int maxn=50000*70+5,maxm=50000+5;
 10 
 11 int n,m,opt,a[maxm];
 12 
 13 int w[maxn],ls[maxn],rs[maxn],fa[maxn],cnt[maxn],siz[maxn],tot;
 14 
 15 inline int read(void){
 16     char ch=getchar();int x=0,f=1;
 17     while(!(ch>='0'&&ch<='9')){
 18         if(ch=='-')
 19             f=-1;
 20         ch=getchar();
 21     }
 22     while(ch>='0'&&ch<='9')
 23         x=x*10+ch-'0',ch=getchar();
 24     return x*f;
 25 }
 26 
 27 struct Splay{
 28     
 29     int root;
 30 
 31     inline void zig(int x){
 32         int y=fa[x],tmp=siz[y];
 33         if(rs[x])
 34             ls[y]=rs[x],fa[rs[x]]=y,siz[y]=siz[y]-siz[x]+siz[rs[x]],siz[x]=tmp;
 35         else
 36             ls[y]=0,siz[y]=siz[y]-siz[x],siz[x]=tmp;
 37         fa[x]=fa[y];
 38         if(fa[x]){
 39             if(ls[fa[x]]==y)
 40                 ls[fa[x]]=x;
 41             else
 42                 rs[fa[x]]=x;
 43         }
 44         fa[y]=x,rs[x]=y;
 45     }
 46     
 47     inline void zag(int x){
 48         int y=fa[x],tmp=siz[y];
 49         if(ls[x])
 50             rs[y]=ls[x],fa[ls[x]]=y,siz[y]=siz[y]-siz[x]+siz[ls[x]],siz[x]=tmp;
 51         else
 52             rs[y]=0,siz[y]=siz[y]-siz[x],siz[x]=tmp;
 53         fa[x]=fa[y];
 54         if(fa[x]){
 55             if(ls[fa[x]]==y)
 56                 ls[fa[x]]=x;
 57             else
 58                 rs[fa[x]]=x;
 59         }
 60         fa[y]=x,ls[x]=y;
 61     }
 62     
 63     inline void splay(int x,int z){
 64         while(fa[x]!=z){
 65             int y=fa[x];
 66             if(fa[y]==z){
 67                 if(ls[y]==x)
 68                     zig(x);
 69                 else
 70                     zag(x);
 71             }
 72             else{
 73                 if(ls[fa[y]]==y){
 74                     if(ls[y]==x)
 75                         zig(y),zig(x);
 76                     else
 77                         zag(x),zig(x);
 78                 }
 79                 else{
 80                     if(rs[y]==x)
 81                         zag(y),zag(x);
 82                     else
 83                         zig(x),zag(x);
 84                 }
 85             }
 86         }
 87         if(!z)
 88             root=x;
 89     }
 90     
 91     inline void ins(int rt,int x){
 92         if(!rt)
 93             w[++tot]=x,siz[tot]=cnt[tot]=1,root=tot;
 94         else{
 95             while(!(w[rt]==x||(x<w[rt]&&!ls[rt])||(x>w[rt]&&!rs[rt]))){
 96                 if(x<w[rt])
 97                     siz[rt]++,rt=ls[rt];
 98                 else if(x>w[rt])
 99                     siz[rt]++,rt=rs[rt];
100             }
101             if(w[rt]==x)
102                 siz[rt]++,cnt[rt]++,splay(rt,0);
103             else if(x<w[rt])
104                 w[++tot]=x,siz[tot]=cnt[tot]=1,siz[rt]++,ls[rt]=tot,fa[tot]=rt,splay(tot,0);
105             else
106                 w[++tot]=x,siz[tot]=cnt[tot]=1,siz[rt]++,rs[rt]=tot,fa[tot]=rt,splay(tot,0);
107         }/*
108         else if(w[rt]==x)
109             siz[rt]++,cnt[rt]++,splay(rt,0);
110         else if(x<w[rt]){
111             if(!ls[rt])
112                 w[++tot]=x,siz[tot]=cnt[tot]=1,siz[rt]++,ls[rt]=tot,fa[tot]=rt,splay(tot,0);
113             else
114                 siz[rt]++,ins(ls[rt],x);
115         }
116         else{
117             if(!rs[rt])
118                 w[++tot]=x,siz[tot]=cnt[tot]=1,siz[rt]++,rs[rt]=tot,fa[tot]=rt,splay(tot,0);
119             else
120                 siz[rt]++,ins(rs[rt],x);
121         }*/
122     }
123     
124     inline void del(int rt,int x){
125         while(w[rt]!=x){
126             if(x<w[rt])
127                 rt=ls[rt];
128             else
129                 rt=rs[rt];
130         }
131         splay(rt,0);
132         if(cnt[rt]>1)
133             cnt[rt]--,siz[rt]--;
134         else{
135             int l=ls[rt],r=rs[rt];
136             if(!l)
137                 ls[rt]=rs[rt]=fa[rt]=cnt[rt]=siz[rt]=0,fa[r]=0,root=r;
138             else{
139                 while(rs[l])
140                     l=rs[l];
141                 splay(l,rt);ls[rt]=rs[rt]=fa[rt]=cnt[rt]=siz[rt]=0;fa[r]=l,rs[l]=r,siz[l]+=siz[r];root=l,fa[l]=0;
142             }
143         }
144     }
145     
146     inline int pre(int rt,int x){
147         int res=-inf;
148         while(rt){
149             if(w[rt]<x)
150                 res=max(res,w[rt]),rt=rs[rt];
151             else
152                 rt=ls[rt];
153         }
154         return res;
155     }
156     
157     inline int suf(int rt,int x){
158         int res=inf;
159         while(rt){
160             if(w[rt]>x)
161                 res=min(res,w[rt]),rt=ls[rt];
162             else
163                 rt=rs[rt];
164         }
165         return res;
166     }
167     
168     inline int rank(int rt,int x){
169         while(w[rt]!=x){
170             if(x<w[rt])
171                 rt=ls[rt];
172             else
173                 rt=rs[rt];
174         }
175         splay(rt,0);
176         if(!ls[rt])
177             return 1;
178         else
179             return siz[ls[rt]]+1;
180     }
181     
182     inline int query(int rt,int x){
183         if(!ls[rt]){
184             if(cnt[rt]>=x){
185                 splay(rt,0);
186                 return w[rt];
187             }
188             else
189                 return query(rs[rt],x-cnt[rt]);
190         }
191         else{
192             if(siz[ls[rt]]>=x)
193                 return query(ls[rt],x);
194             else if(siz[ls[rt]]+cnt[rt]>=x){
195                 splay(rt,0);
196                 return w[rt];
197             }
198             else
199                 return query(rs[rt],x-siz[ls[rt]]-cnt[rt]);
200         }
201     }
202     
203 };
204 
205 struct Tree{
206     int l,r;
207     Splay s;
208 }tree[maxm*4];
209 
210 inline void build(int l,int r,int tr){
211     tree[tr].l=l,tree[tr].r=r;
212     for(int i=l;i<=r;i++)
213         tree[tr].s.ins(tree[tr].s.root,a[i]);
214     if(l==r)
215         return;
216     int mid=(l+r)>>1;
217     build(l,mid,tr<<1);build(mid+1,r,tr<<1|1);
218 }
219 /*
220 inline void insert(int tr,int pos,int x){
221     tree[tr].s.ins(tree[tr].s.root,x);
222     if(tree[tr].l==tree[tr].r)
223         return;
224     int mid=(tree[tr].l+tree[tr].r)>>1;
225     if(pos<=mid)
226         insert(tr<<1,pos,x);
227     else
228         insert(tr<<1|1,pos,x);
229 }
230 */
231 inline int qryrank(int tr,int l,int r,int x){
232     int lala;
233     if(tree[tr].l==l&&tree[tr].r==r)
234         return tree[tr].s.ins(tree[tr].s.root,x),lala=tree[tr].s.rank(tree[tr].s.root,x)-1,tree[tr].s.del(tree[tr].s.root,x),lala;
235     int mid=(tree[tr].l+tree[tr].r)>>1;
236     if(r<=mid)
237         return qryrank(tr<<1,l,r,x);
238     else if(l>mid)
239         return qryrank(tr<<1|1,l,r,x);
240     else
241         return qryrank(tr<<1,l,mid,x)+qryrank(tr<<1|1,mid+1,r,x);
242 }
243 
244 inline void change(int tr,int pos,int x){
245     tree[tr].s.del(tree[tr].s.root,a[pos]),tree[tr].s.ins(tree[tr].s.root,x);
246     if(tree[tr].l==tree[tr].r)
247         return;
248     int mid=(tree[tr].l+tree[tr].r)>>1;
249     if(pos<=mid)
250         change(tr<<1,pos,x);
251     else
252         change(tr<<1|1,pos,x);
253 }
254 
255 inline int qrypre(int tr,int l,int r,int x){
256     if(tree[tr].l==l&&tree[tr].r==r)
257         return tree[tr].s.pre(tree[tr].s.root,x);
258     int mid=(tree[tr].l+tree[tr].r)>>1;
259     if(r<=mid)    
260         return qrypre(tr<<1,l,r,x);
261     else if(l>mid)
262         return qrypre(tr<<1|1,l,r,x);
263     else
264         return max(qrypre(tr<<1,l,mid,x),qrypre(tr<<1|1,mid+1,r,x));
265 }
266 
267 inline int qrysuf(int tr,int l,int r,int x){
268     if(tree[tr].l==l&&tree[tr].r==r)
269         return tree[tr].s.suf(tree[tr].s.root,x);
270     int mid=(tree[tr].l+tree[tr].r)>>1;
271     if(r<=mid)
272         return qrysuf(tr<<1,l,r,x);
273     else if(l>mid)
274         return qrysuf(tr<<1|1,l,r,x);
275     else
276         return min(qrysuf(tr<<1,l,mid,x),qrysuf(tr<<1|1,mid+1,r,x));
277 }
278 
279 signed main(void){
280 //    freopen("3196.in","r",stdin);
281 //    freopen("3196.out","w",stdout);
282     memset(ls,0,sizeof(ls));
283     memset(rs,0,sizeof(rs));
284     memset(fa,0,sizeof(fa));
285     memset(cnt,0,sizeof(cnt));
286     memset(siz,0,sizeof(siz));
287     n=read(),m=read();
288     for(int i=1;i<=n;i++)
289         a[i]=read();//,insert(1,i,a[i]);
290     build(1,n,1);
291     for(int i=1,l,r,x;i<=m;i++){
292         opt=read();
293         if(opt==1){
294             l=read(),r=read(),x=read();
295             printf("%d\n",qryrank(1,l,r,x)+1);
296         }
297         else if(opt==2){
298             l=read(),r=read(),x=read();
299             int lef=1,rig=n,ans;
300             while(lef<=rig){
301                 int mid=(lef+rig)>>1,tmp=tree[1].s.query(tree[1].s.root,mid);
302                 if(qryrank(1,l,r,tmp)<=x-1)
303                     lef=mid+1,ans=tmp;
304                 else
305                     rig=mid-1;
306             }
307             printf("%d\n",ans);
308         }
309         else if(opt==3){
310             l=read(),x=read();
311             change(1,l,x);a[l]=x;
312         }
313         else if(opt==4){
314             l=read(),r=read(),x=read();
315             printf("%d\n",qrypre(1,l,r,x));
316         }
317         else if(opt==5){
318             l=read(),r=read(),x=read();
319             printf("%d\n",qrysuf(1,l,r,x));
320         }
321     }
322     return 0;
323 }
View Code

by NeighThorn

posted @ 2016-12-12 09:49  NeighThorn  阅读(236)  评论(0编辑  收藏  举报