题目描述
您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:
-
查询k在区间内的排名
-
查询区间内排名为k的值
-
修改某一位值上的数值
-
查询k在区间内的前驱(前驱定义为严格小于x,且最大的数,若不存在输出-2147483647)
- 查询k在区间内的后继(后继定义为严格大于x,且最小的数,若不存在输出2147483647)
注意上面两条要求和tyvj或者bzoj不一样,请注意
输入输出格式
输入格式:第一行两个数 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的后继
输出格式:对于操作1,2,4,5各输出一行,表示查询结果
输入输出样例
输入样例#1: 复制
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
输出样例#1: 复制
2 4 3 4 9
说明
时空限制:2s,128M
n,m leq 5cdot {10}^4n,m≤5⋅104 保证有序序列所有值在任何时刻满足 [0, {10} ^8][0,108]
题目来源:bzoj3196 / Tyvj1730 二逼平衡树,在此鸣谢
此数据为洛谷原创。(特别提醒:此数据不保证操作5、6一定存在,故请务必考虑不存在的情况)
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #define maxn 50010 5 #define maxm 50010*400 6 using namespace std; 7 int n,m,tot,root[maxn],a[maxn],hash[maxn*2],A[20],B[20]; 8 struct node{int op,opl,opr,opk;}e[maxn]; 9 struct S_T{ 10 int cnt,lc[maxm],rc[maxm],sum[maxm]; 11 void insert(int &k,int l,int r,int pos,int w){ 12 if(!k)k=++cnt; 13 sum[k]+=w; 14 if(l==r)return; 15 int mid=(l+r)>>1; 16 if(pos<=mid)insert(lc[k],l,mid,pos,w); 17 else insert(rc[k],mid+1,r,pos,w); 18 } 19 int getrank(int l,int r,int w,bool ty){ 20 int tmp=0; 21 if(l==r){ 22 if(!ty)return 0; 23 else{ 24 for(int i=1;i<=A[0];i++)tmp+=sum[A[i]]; 25 for(int i=1;i<=B[0];i++)tmp-=sum[B[i]]; 26 return tmp; 27 } 28 } 29 for(int i=1;i<=A[0];i++)tmp+=sum[lc[A[i]]]; 30 for(int i=1;i<=B[0];i++)tmp-=sum[lc[B[i]]]; 31 int mid=(l+r)>>1; 32 if(w<=mid){ 33 for(int i=1;i<=A[0];i++)A[i]=lc[A[i]]; 34 for(int i=1;i<=B[0];i++)B[i]=lc[B[i]]; 35 return getrank(l,mid,w,ty); 36 } 37 else { 38 for(int i=1;i<=A[0];i++)A[i]=rc[A[i]]; 39 for(int i=1;i<=B[0];i++)B[i]=rc[B[i]]; 40 return tmp+getrank(mid+1,r,w,ty); 41 } 42 } 43 int getnum(int l,int r,int w){ 44 if(l==r)return hash[l]; 45 int tmp=0; 46 for(int i=1;i<=A[0];i++)tmp+=sum[lc[A[i]]]; 47 for(int i=1;i<=B[0];i++)tmp-=sum[lc[B[i]]]; 48 int mid=(l+r)>>1; 49 if(w<=tmp){ 50 for(int i=1;i<=A[0];i++)A[i]=lc[A[i]]; 51 for(int i=1;i<=B[0];i++)B[i]=lc[B[i]]; 52 return getnum(l,mid,w); 53 } 54 else{ 55 for(int i=1;i<=A[0];i++)A[i]=rc[A[i]]; 56 for(int i=1;i<=B[0];i++)B[i]=rc[B[i]]; 57 return getnum(mid+1,r,w-tmp); 58 } 59 } 60 }ST; 61 struct B_I_T{ 62 void add(int pos,int key,int val){ 63 while(pos<=n){ 64 ST.insert(root[pos],1,tot,key,val); 65 pos+=pos&(-pos); 66 } 67 } 68 int qrank(int l,int r,int k,bool ty){ 69 A[0]=0;while(r)A[++A[0]]=root[r],r-=r&(-r); 70 B[0]=0;while(l)B[++B[0]]=root[l],l-=l&(-l); 71 return ST.getrank(1,tot,k,ty); 72 } 73 int qnum(int l,int r,int k){ 74 A[0]=0;while(r)A[++A[0]]=root[r],r-=r&(-r); 75 B[0]=0;while(l)B[++B[0]]=root[l],l-=l&(-l); 76 return ST.getnum(1,tot,k); 77 } 78 void modify(int pos,int w){ 79 A[0]=0;int tmp=pos; 80 while(pos<=n)A[++A[0]]=pos,pos+=pos&(-pos); 81 for(int i=1;i<=A[0];i++)ST.insert(root[A[i]],1,tot,a[tmp],-1); 82 for(int i=1;i<=A[0];i++)ST.insert(root[A[i]],1,tot,w,1); 83 a[tmp]=w; 84 } 85 }BIT; 86 int main(){ 87 scanf("%d%d",&n,&m); 88 for(int i=1;i<=n;i++)scanf("%d",&a[i]),hash[i]=a[i]; 89 int opt,l,r,k,tmp=n; 90 for(int i=1;i<=m;i++){ 91 scanf("%d",&opt); 92 if(opt==3)scanf("%d%d",&l,&k); 93 else scanf("%d%d%d",&l,&r,&k); 94 e[i].op=opt;e[i].opl=l;e[i].opk=k; 95 if(opt!=3)e[i].opr=r; 96 if(opt!=2)hash[++tmp]=k; 97 } 98 sort(hash+1,hash+tmp+1); 99 tot=unique(hash+1,hash+tmp+1)-(hash+1); 100 for(int i=1;i<=n;i++){ 101 a[i]=lower_bound(hash+1,hash+tot+1,a[i])-hash; 102 BIT.add(i,a[i],1); 103 } 104 for(int i=1;i<=m;i++) 105 if(e[i].op!=2)e[i].opk=lower_bound(hash+1,hash+tot+1,e[i].opk)-hash; 106 107 for(int i=1;i<=m;i++){ 108 if(e[i].op==1)printf("%d ",BIT.qrank(e[i].opl-1,e[i].opr,e[i].opk,0)+1); 109 else if(e[i].op==2)printf("%d ",BIT.qnum(e[i].opl-1,e[i].opr,e[i].opk)); 110 else if(e[i].op==3)BIT.modify(e[i].opl,e[i].opk); 111 else if(e[i].op==4){ 112 int tmp=BIT.qrank(e[i].opl-1,e[i].opr,e[i].opk,0); 113 if(!tmp)puts("-2147483647"); 114 else printf("%d ",BIT.qnum(e[i].opl-1,e[i].opr,tmp)); 115 } 116 else{ 117 int tmp=BIT.qrank(e[i].opl-1,e[i].opr,e[i].opk,1); 118 if(tmp==e[i].opr-e[i].opl+1)puts("2147483647"); 119 else printf("%d ",BIT.qnum(e[i].opl-1,e[i].opr,tmp+1)); 120 } 121 } 122 }