带修的区间第k大
只要在修改操作之前将原数删除一下即可 (整体二分最外层是维护时间轴的!!!!! 操作过程中永远保证时间轴有序 )
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
// luogu-judger-enable-o2 #include<bits/stdc++.h> using namespace std; #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define repp(i,a,b) for(int i=(a);i>=(b);--i) #define ll long long #define see(x) (cerr<<(#x)<<'='<<(x)<<endl) #define inf 0x3f3f3f3f #define CLR(A,v) memset(A,v,sizeof A) / const int N=1e6+10; int n,m,t[N],k,ans[N],cnt,a[N],tot; void add(int x,int v){for(;x<=N;x+=x&-x)t[x]+=v;} int qsum(int x){int ans=0;for(;x;x-=x&-x)ans+=t[x];return ans;} struct node{int l,r,k,op,id;}s[N],temp1[N],temp2[N]; void cdq(int l,int r,int L,int R) { if(L>R)return ; if(l==r) { rep(i,L,R)if(s[i].op==2)ans[s[i].id]=l; return ; } int mid=(l+r)>>1,cnt1=0,cnt2=0; rep(i,L,R) { if(s[i].op==1) { if(s[i].l<=mid)add(s[i].id,s[i].r),temp1[++cnt1]=s[i]; else temp2[++cnt2]=s[i]; } else { int x=qsum(s[i].r)-qsum(s[i].l-1); if(s[i].k<=x)temp1[++cnt1]=s[i]; else s[i].k-=x,temp2[++cnt2]=s[i]; } } rep(i,1,cnt1)if(temp1[i].op==1)add(temp1[i].id,-temp1[i].r); rep(i,1,cnt1)s[L-1+i]=temp1[i]; rep(i,1,cnt2)s[L+cnt1-1+i]=temp2[i]; cdq(l,mid,L,L+cnt1-1); cdq(mid+1,r,L+cnt1,R); } int main() { cin>>n>>m; rep(i,1,n) cnt++,scanf("%d",&s[cnt].l),s[cnt].r=1,s[cnt].k=0,s[cnt].id=i,s[cnt].op=1,a[i]=s[cnt].l; rep(i,1,m) { int l,r,k;char ss[2];scanf("%s",ss); if(ss[0]=='Q') scanf("%d%d%d",&l,&r,&k),s[++cnt]=(node){l,r,k,2,++tot}; else scanf("%d%d",&l,&r),s[++cnt]=(node){a[l],-1,0,1,l},s[++cnt]=(node){a[l]=r,1,0,1,l}; } cdq(-inf,inf,1,cnt); rep(i,1,tot) printf("%d\n",ans[i]); return 0; }