#include<bits/stdc++.h>
using namespace std;
//树状数组
int BIT[500005];
int lowbit(int x){return x&-x;}
void update(int x,int y){
for(int i=x;i<=500000;i+=lowbit(i))BIT[i]+=y;
}
int query(int l,int r){
int a=0,b=0;
for(int i=l-1;i>=1;i-=lowbit(i))a+=BIT[i];
for(int i=r;i>=1;i-=lowbit(i))b+=BIT[i];
return b-a;
}
//使用结构体存入查询与修改
struct st{
int ty,l,r,x,id,f;
};
int ans[500005];//存答案
void solve(int L,int R,vector<st> kk){
if(L==R){
for(int i=0;i<kk.size();i++)if(kk[i].ty==2)ans[kk[i].id]=L;
return;
}
int mid=L+R>>1;
vector<st>a1,a2;
for(int i=0;i<kk.size();i++){//将其分为左右两部分
if(kk[i].ty==2){
int kkk=query(kk[i].l,kk[i].r);
if(kk[i].x<=kkk)a1.push_back(kk[i]);
else kk[i].x-=kkk,a2.push_back(kk[i]);
}else{
if(kk[i].x<=mid)a1.push_back(kk[i]),update(kk[i].id,kk[i].f);
else a2.push_back(kk[i]);
}
}
for(int i=0;i<kk.size();i++){
if(kk[i].ty==1&&kk[i].x<=mid)update(kk[i].id,-kk[i].f);
}//清零树状数组
solve(L,mid,a1),solve(mid+1,R,a2);//递归求解
}
vector<st>a;
st rpp[500005];
int op[500005],rp[500005];
int lsh(int x){
int n=0;
for(int i=1;i<=x;i++){
if(rpp[i].ty==1)rp[++n]=rpp[i].x;
}
sort(rp+1,rp+n+1);
long long len=unique(rp+1,rp+n+1)-(rp+1);
for(long long i=1;i<=x;i++){
if(rpp[i].ty==1){
int l=1,r=len;
while(l<r){
int mid=l+r+1>>1;
if(rp[mid]>rpp[i].x)r=mid-1;
else l=mid;
}
op[l]=rpp[i].x,rpp[i].x=l;
}
a.push_back(rpp[i]);
}
return len;
}
int n,m,cnt,v[500005];
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
cnt++;
scanf("%d",&rpp[cnt].x);
v[i]=rpp[cnt].x,rpp[cnt].id=cnt,rpp[cnt].ty=1,rpp[cnt].f=1;
}//将输入看做修改
for(int i=1,x,y;i<=m;i++){
char s[5];
scanf("%s",s);
if(s[0]=='Q'){
cnt++;
scanf("%d%d%d",&rpp[cnt].l,&rpp[cnt].r,&rpp[cnt].x);
rpp[cnt].id=cnt,rpp[cnt].ty=2;//查询
}else{
scanf("%d%d",&x,&y);
cnt++;
rpp[cnt].id=x,rpp[cnt].x=v[x],rpp[cnt].f=-1,rpp[cnt].ty=1;
cnt++;
rpp[cnt].id=x,rpp[cnt].x=y,rpp[cnt].f=1,rpp[cnt].ty=1;
v[x]=y;//修改
}
}
solve(1,lsh(cnt),a);//进行离散化,优化常数
for(int i=1;i<=cnt;i++){
if(rpp[i].ty==2)printf("%d\n",op[ans[i]]);
}
return 0;
}
Dynamic Rankings 整体二分 代码
于 2022-02-16 22:01:41 首次发布