[BZOJ3196]二逼平衡树

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
 
树状数组套线段树,PS:yyb的代码真好看
代码:
  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #define M 100010
  6 #define ls ch[node][0]
  7 #define rs ch[node][1]
  8 using namespace std;
  9 int read() {
 10     char ch=getchar();int x=0,f=1;
 11     while(ch>'9'||ch<'0') {if(ch=='-')f=-1;ch=getchar();}
 12     while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
 13     return x*f;
 14 }
 15 int n,m,cnt,tot,tx,ty;
 16 int rt[M],a[M],b[M],qx[M],qy[M],opt[M],ql[M],qr[M],qk[M];
 17 int val[M<<6],ch[M<<6][2];
 18 void insert(int &node,int l,int r,int x,int v) {
 19     if(!node) node=++cnt;val[node]+=v;
 20     if(l==r) return;
 21     int mid=(l+r)>>1;
 22     if(x<=mid) insert(ls,l,mid,x,v);
 23     else insert(rs,mid+1,r,x,v);
 24 }
 25 int query(int node,int l,int r,int x) {
 26     if(l==r) return val[node];
 27     int mid=(l+r)>>1;
 28     if(x<=mid) return query(ls,l,mid,x);
 29     else return val[ls]+query(rs,mid+1,r,x);
 30 }
 31 void change(int loc,int v) {
 32     for(int i=loc;i<=n;i+=(i&-i))
 33         insert(rt[i],1,tot,a[loc],v);
 34 }
 35 int Rank(int l,int r,int k) {
 36     int ans=0;
 37     for(int i=l-1;i;i-=(i&-i)) ans-=query(rt[i],1,tot,k);
 38     for(int i=r;i;i-=(i&-i)) ans+=query(rt[i],1,tot,k);
 39     return ans; 
 40 }
 41 int findx(int l,int r,int k) {
 42     if(l==r) return l;
 43     int sum=0,mid=(l+r)>>1;
 44     for(int i=1;i<=tx;i++) sum-=val[ch[qx[i]][0]];
 45     for(int i=1;i<=ty;i++) sum+=val[ch[qy[i]][0]];
 46     if(k<=sum) {
 47         for(int i=1;i<=tx;i++) qx[i]=ch[qx[i]][0];
 48         for(int i=1;i<=ty;i++) qy[i]=ch[qy[i]][0];
 49         return findx(l,mid,k);
 50     }
 51     else{
 52         for(int i=1;i<=tx;i++) qx[i]=ch[qx[i]][1];
 53         for(int i=1;i<=ty;i++) qy[i]=ch[qy[i]][1];
 54         return findx(mid+1,r,k-sum);
 55     }
 56 }
 57 int kth(int l,int r,int k) {
 58     tx=ty=0;
 59     for(int i=l-1;i;i-=(i&-i)) qx[++tx]=rt[i];
 60     for(int i=r;i;i-=(i&-i)) qy[++ty]=rt[i];
 61     return b[findx(1,tot,k)];
 62 }
 63 int main() {
 64     n=read();m=read();
 65     for(int i=1;i<=n;i++) a[i]=b[++tot]=read();
 66     for(int i=1;i<=m;i++) {
 67         opt[i]=read();
 68         if(opt[i]!=3) {
 69             ql[i]=read(),qr[i]=read(),qk[i]=read();
 70             if(opt[i]!=2) b[++tot]=qk[i];
 71         }
 72         else{
 73             ql[i]=read(),qr[i]=read();
 74             b[++tot]=qr[i];
 75         } 
 76     }
 77     sort(b+1,b+1+tot);
 78     tot=unique(b+1,b+1+tot)-b-1;
 79     for(int i=1;i<=n;i++) {
 80         a[i]=lower_bound(b+1,b+1+tot,a[i])-b;
 81         change(i,1);
 82     }
 83     for(int i=1;i<=m;i++) {
 84         if(opt[i]==1) {
 85             int k=lower_bound(b+1,b+1+tot,qk[i])-b;
 86             printf("%d\n",Rank(ql[i],qr[i],k-1)+1);
 87         }
 88         if(opt[i]==2) printf("%d\n",kth(ql[i],qr[i],qk[i]));
 89         if(opt[i]==3) {
 90             change(ql[i],-1);
 91             a[ql[i]]=lower_bound(b+1,b+1+tot,qr[i])-b;
 92             change(ql[i],1);
 93         }
 94         if(opt[i]==4) {
 95             int x=lower_bound(b+1,b+1+tot,qk[i])-b;
 96             int k=Rank(ql[i],qr[i],x-1);
 97             printf("%d\n",kth(ql[i],qr[i],k));
 98         }
 99         if(opt[i]==5) {
100             int x=lower_bound(b+1,b+1+tot,qk[i])-b;
101             int k=Rank(ql[i],qr[i],x);
102             printf("%d\n",kth(ql[i],qr[i],k+1));
103         }
104     }
105     return 0;
106 }

 

posted @ 2018-12-04 19:06  Slr  阅读(129)  评论(0编辑  收藏  举报