n<=10000个数有m<=10000个操作,1、询问一个区间的第k小的数;2、单点修改。
带修主席树。
整体二分。
整体二分的必要条件:
1 #include<string.h> 2 #include<stdlib.h> 3 #include<stdio.h> 4 //#include<assert.h> 5 #include<algorithm> 6 //#include<iostream> 7 using namespace std; 8 9 int n,m; 10 #define maxn 30011 11 const int inf=0x3f3f3f3f; 12 struct Ope 13 { 14 int x,y,z,id,type; 15 //type=1: 询问区间[x,y]第z大,询问编号id 16 //type=0:把位置x的数修改为y,增加:z=1,删除:z=-1 17 }q[maxn],al[maxn],ar[maxn];int len; 18 int ans[maxn]; 19 20 struct BIT 21 { 22 int a[maxn]; 23 void add(int x,int v) {for (;x<=n;x+=x&-x) a[x]+=v;} 24 int query(int x) {int ans=0; for (;x;x-=x&-x) ans+=a[x]; return ans;} 25 }t; 26 27 void solve(int L,int R,int ql,int qr) 28 { 29 if (L>R || ql>qr) return; 30 if (L==R) 31 { 32 for (int i=ql;i<=qr;i++) if (q[i].type) ans[q[i].id]=L; 33 return; 34 } 35 int mid=(L+R)>>1,lql=0,lqr=0; 36 for (int i=ql;i<=qr;i++) 37 { 38 if (q[i].type) 39 { 40 int tmp=t.query(q[i].y)-t.query(q[i].x-1); 41 if (tmp>=q[i].z) al[++lql]=q[i]; 42 else 43 { 44 q[i].z-=tmp; 45 ar[++lqr]=q[i]; 46 } 47 } 48 else 49 { 50 if (q[i].y<=mid) 51 { 52 t.add(q[i].x,q[i].z); 53 al[++lql]=q[i]; 54 } 55 else ar[++lqr]=q[i]; 56 } 57 } 58 for (int i=1;i<=lql;i++) if (al[i].type==0) t.add(al[i].x,-al[i].z); 59 for (int i=1,j=ql;i<=lql;i++,j++) q[j]=al[i]; 60 for (int i=1,j=ql+lql;i<=lqr;i++,j++) q[j]=ar[i]; 61 solve(L,mid,ql,ql+lql-1); 62 solve(mid+1,R,ql+lql,qr); 63 } 64 65 int a[maxn]; 66 int main() 67 { 68 scanf("%d%d",&n,&m); 69 for (int i=1;i<=n;i++) scanf("%d",&q[i].y),a[i]=q[i].y,q[i].x=i,q[i].z=1,q[i].type=0; 70 char s[5]; 71 int cntq=0; 72 for (int i=1,j=n+1;i<=m;i++,j++) 73 { 74 scanf("%s",s); 75 if (s[0]=='Q') scanf("%d%d%d",&q[j].x,&q[j].y,&q[j].z),q[j].id=++cntq,q[j].type=1; 76 else scanf("%d%d",&q[j].x,&q[j].y),q[j].z=1,q[j].type=0, 77 q[j+1]=(Ope){q[j].x,a[q[j].x],-1,0,0},a[q[j].x]=q[j].y,j++; 78 if (i==m) len=j; 79 } 80 solve(0,inf,1,len); 81 for (int i=1;i<=cntq;i++) printf("%d ",ans[i]); 82 return 0; 83 }