首页 > 代码库 > Bzoj3196 Tyvj 1730 二逼平衡树

Bzoj3196 Tyvj 1730 二逼平衡树

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 3350  Solved: 1324

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

 

树套树

线段树套平衡树(treap)

外层线段树维护区间,内层treap维护该区间内的数值

代码超长看着就累

Bzoj过了,Tyvj上最后两个点过不去,迷

标题仿佛在嘲笑那些光写平衡树的人,又仿佛在嘲讽我这种模板题调一下午的人……

小发现:对拍的时候,要是每次错得不一样,基本上可以确定是旋转错了/结点删错了

  1 #include<iostream>  2 #include<cstdio>  3 #include<algorithm>  4 #include<cstring>  5 #include<cstdlib>  6 #include<ctime>  7 using namespace std;  8 const int mxn=50010;  9 int read(){ 10     int x=0,f=1;char ch=getchar(); 11     while(ch<0 || ch>9){if(ch==-)f=-1;ch=getchar();} 12     while(ch>=0 && ch<=9){x=x*10-0+ch;ch=getchar();} 13     return x*f; 14 } 15 int n,m,root[mxn<<2]; 16 struct node{ 17     int l,r;int w,rand;int cnt,size; 18 }t[mxn*60]; 19 int cnt=0; 20 void pushup(int rt){ 21     t[rt].size=t[t[rt].l].size+t[t[rt].r].size+t[rt].cnt;return; 22 } 23 void lturn(int &rt){ 24     int tmp=t[rt].r; 25     t[rt].r=t[tmp].l; t[tmp].l=rt; 26     t[tmp].size=t[rt].size; 27     pushup(rt);    rt=tmp; 28     return; 29 } 30 void rturn(int &rt){ 31     int tmp=t[rt].l; 32     t[rt].l=t[tmp].r; t[tmp].r=rt; 33     t[tmp].size=t[rt].size; 34     pushup(rt);    rt=tmp; 35     return; 36 } 37 void insert(int w,int &rt){ 38     if(!rt){ 39         rt=++cnt; 40         t[rt].l=t[rt].r=0; 41         t[rt].size=t[rt].cnt=1; 42         t[rt].rand=rand(); 43         t[rt].w=w; 44         return; 45     } 46     t[rt].size++; 47     if(t[rt].w==w){t[rt].cnt++;return;} 48     if(w<t[rt].w){insert(w,t[rt].l);if(t[t[rt].l].rand>t[rt].rand)rturn(rt);} 49     else {insert(w,t[rt].r);if(t[t[rt].r].rand>t[rt].rand)lturn(rt);} 50     return; 51 } 52 void Del(int w,int &rt){ 53     if(t[rt].w==w){ 54         if(t[rt].cnt>1){t[rt].cnt--;t[rt].size--;return;} 55         if(t[rt].l*t[rt].r==0)rt=t[rt].l+t[rt].r; 56         else  57             if(t[t[rt].l].rand>t[t[rt].r].rand) 58             {rturn(rt);Del(w,rt);} 59             else{lturn(rt);Del(w,rt);}//开始写成Del(w,t[rt].l) WA了  60         return; 61     } 62     else if(w>t[rt].w)Del(w,t[rt].r); 63         else Del(w,t[rt].l); 64     t[rt].size--; 65     return; 66 } 67 // 68 void Build(int p,int v,int l,int r,int rt){ 69     insert(v,root[rt]); 70     if(l==r)return; 71     int mid=(l+r)>>1; 72     if(p<=mid)Build(p,v,l,mid,rt<<1); 73     else Build(p,v,mid+1,r,rt<<1|1); 74     return; 75 } 76 void update(int p,int last,int v,int l,int r,int rt){//改变某位置的值  77 //    printf("p:%d last:%d v:%d l:%d r:%d rt:%d\n",p,last,v,l,r,rt); 78     Del(last,root[rt]);//删除旧值  79     insert(v,root[rt]);//添加新值  80     if(l==r)return; 81     int mid=(l+r)>>1; 82     if(p<=mid)update(p,last,v,l,mid,rt<<1); 83     else update(p,last,v,mid+1,r,rt<<1|1); 84     return; 85 } 86 // 87 int rank1(int w,int rt){ 88     if(!rt)return 0; 89     if(w==t[rt].w){return t[t[rt].l].size;} 90     if(w<t[rt].w)return rank1(w,t[rt].l); 91     else return t[t[rt].l].size+t[rt].cnt+rank1(w,t[rt].r); 92 } 93 int Qrk(int L,int R,int num,int l,int r,int rt){//查找num的排名  94     if(L<=l && r<=R)return rank1(num,root[rt]); 95     int mid=(l+r)>>1; 96     int res=0; 97     if(L<=mid)res+=Qrk(L,R,num,l,mid,rt<<1); 98     if(R>mid)res+=Qrk(L,R,num,mid+1,r,rt<<1|1); 99     return res;100 }101 int Qnum(int L,int R,int k){//查找排名为k的数 102     int l=0,r=1e9,ans=0;103     while(l<=r){//二分答案 104         int mid=(l+r)>>1;105         int res=Qrk(L,R,mid,1,n,1)+1;106         if(res<=k){l=mid+1;ans=mid;}107         else r=mid-1;108     }109     return ans;110 }111 int res=0;//存储前驱/后继答案112 void Pre(int w,int rt){113     if(!rt)return;114     if(t[rt].w<w){res=max(res,t[rt].w);Pre(w,t[rt].r);}115     else Pre(w,t[rt].l);116     return;117 }118 void Sub(int w,int rt){119     if(!rt)return;120     if(t[rt].w>w){res=min(res,t[rt].w);Sub(w,t[rt].l);}121     else Sub(w,t[rt].r);122     return;123 }124 void Qpre(int L,int R,int num,int l,int r,int rt){125     if(L<=l && r<=R){Pre(num,root[rt]);return;}126     int mid=(l+r)>>1;127     if(L<=mid)Qpre(L,R,num,l,mid,rt<<1);128     if(R>mid)Qpre(L,R,num,mid+1,r,rt<<1|1);129     return;130 }131 void Qsub(int L,int R,int num,int l,int r,int rt){132 //    printf("!\n");133     if(L<=l && r<=R){Sub(num,root[rt]);return;}134     int mid=(l+r)>>1;135     if(L<=mid)Qsub(L,R,num,l,mid,rt<<1);136     if(R>mid)Qsub(L,R,num,mid+1,r,rt<<1|1);137     return;138 }139 int a[mxn];140 int main(){141     int i,j,x,y,w;142     n=read();m=read();143     srand(time(0));144     for(i=1;i<=n;i++){a[i]=read();Build(i,a[i],1,n,1);}145     int op;146     while(m--){147         op=read();148         switch(op){149             case 1:{150                 x=read();y=read();w=read();151                 printf("%d\n",Qrk(x,y,w,1,n,1)+1);152                 break;153             }154             case 2:{155                 x=read();y=read();w=read();156                 printf("%d\n",Qnum(x,y,w));157                 break;158             }159             case 3:{160                 x=read();y=read();161                 update(x,a[x],y,1,n,1);162                 a[x]=y;163                 break;164             }165             case 4:{166                 x=read();y=read();w=read();167                 res=-1e9;168                 Qpre(x,y,w,1,n,1);169                 printf("%d\n",res);170                 break;171             }172             case 5:{173                 x=read();y=read();w=read();174                 res=1e9;175                 Qsub(x,y,w,1,n,1);176                 printf("%d\n",res);177                 break;178             }179         }180     }181     return 0;182 }

 

Bzoj3196 Tyvj 1730 二逼平衡树