#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+7;
int block,num,L[maxn],R[maxn],belong[maxn];
int lazy[maxn],a[maxn],b[maxn],c[maxn]; //a排序,b临时,c原数组
int n,q;
int Lower_bound(int arr[],int l,int r,int w){
int mid=(l+r)/2;
while(l<r){
if(arr[mid]>=w)
r=mid;
else l=mid+1;
mid=(l+r)/2;
}
return l;
}
void Build(){
block=sqrt(n);//块大小
num=n/block;//块数
if(n%block) num++;
for(int i=1;i<=num;++i) //每个块的左右端点
L[i]=(i-1)*block+1,R[i]=i*block;
R[num]=n;
for(int i=1;i<=n;++i){ //每个点所在的块
belong[i]=(i-1)/block+1;
}
for(int i=1;i<=n;++i){
a[i]=c[i];
}
for(int i=1;i<=num;++i){
sort(a+L[i],a+R[i]+1);
}
}
void update(int ll,int rr,int w){
int bl,br;
if(belong[ll]==belong[rr]){
bl=belong[ll];
for(int i=ll;i<=rr;++i){
c[i]+=w;
}
for(int i=L[bl];i<=R[bl];++i){
a[i]=c[i];
}
sort(a+L[bl],a+R[bl]+1);
return ;
}
bl=belong[ll],br=belong[rr];
for(int i=ll;i<=R[bl];++i){
c[i]+=w;
}
for(int i=L[bl];i<=R[bl];++i){
a[i]=c[i];
}
sort(a+L[bl],a+R[bl]+1);
for(int i=bl+1;i<=br-1;++i){
lazy[i]+=w;
}
for(int i=L[br];i<=rr;++i){
c[i]+=w;
}
for(int i=L[br];i<=R[br];++i){
a[i]=c[i];
}
sort(a+L[br],a+R[br]+1);
}
int query(int ll,int rr,int w){
int pos,res=0;
int bl=belong[ll],br=belong[rr];
if(bl==br){
for(int i=ll;i<=rr;++i){
b[i]=c[i]+lazy[bl];
}
sort(b+ll,b+rr+1);
pos=Lower_bound(b,ll,rr,w);
if(!(pos==rr&&b[pos]<w))
res+=rr-pos+1;
return res;
}
for(int i=ll;i<=R[bl];++i){
b[i]=c[i]+lazy[bl];
}
sort(b+ll,b+R[bl]+1);
pos=Lower_bound(b,ll,R[bl],w);
if(!(pos==R[bl]&&b[pos]<w))
res+=R[bl]-pos+1;
for(int i=L[br];i<=rr;++i){
b[i]=c[i]+lazy[br];
}
sort(b+L[br],b+rr+1);
pos=Lower_bound(b,L[br],rr,w);
if(!(pos==rr&&b[pos]<w)){
res+=rr-pos+1;
}
for(int i=bl+1;i<=br-1;++i){
pos=Lower_bound(a,L[i],R[i],w-lazy[i]);
if(!(pos==R[i]&&a[pos]<w-lazy[i]))
res+=R[i]-pos+1;
}
return res;
}
void get(char &ch){
ch=getchar();
while((ch<'a'||ch>'z')&&(ch<'A'||ch>'Z'))ch=getchar();
}
int read(){
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9'){
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9'){
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return x*f;
}
int main(){
int q;
n=read();q=read();
for(int i=1;i<=n;++i){
c[i]=read();
}
Build();
while(q--){
char opt;
int l,r,v;
get(opt);l=read();r=read();v=read();
if(opt=='A'){
printf("%d\n",query(l,r,v));
}
else {
update(l,r,v);
}
}
return 0;
}
来源:CSDN
作者:hellocode1024
链接:https://blog.csdn.net/weixin_43769146/article/details/103244579