題意:區間修改,然後查詢區間內小於x的元素的值的個數。
思路:依舊考慮分塊,對於已經在區間內的完整的塊,可以先對塊排序,然後直接二分,對於不完整的塊依舊暴力查詢,注意在每次修改後保證快內元素的有序性。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn=1e5+5;
vector<LL>v[1005];
char ch[20];
LL a[maxn],tag[maxn];
int blo,n,m;
int xx;
int l,r,bl[maxn];
void reset(int x) {
v[x].clear();
for(int i=(x-1)*blo+1;i<=min(x*blo,n);i++)
v[x].push_back(a[i]);
sort(v[x].begin(),v[x].end());
}
void change(int l,int r,int x) {
for(int i=l;i<=min(r,blo*bl[l]);i++)
a[i]+=x;
reset(bl[l]);
if(bl[l]!=bl[r]) {
for(int i=(bl[r]-1)*blo+1;i<=r;i++)
a[i]+=x;
reset(bl[r]);
}
for(int i=bl[l]+1;i<=bl[r]-1;i++)
tag[i]+=x;
}
int search(int l,int r,int x) {
int ans=0;
for(int i=l;i<=min(r,blo*bl[l]);i++) {
if(a[i]+tag[bl[l]]<x) ans++;
}
if (bl[l]!=bl[r]){
for (int i=(bl[r]-1)*blo+1;i<=r;i++)
if (a[i]+tag[bl[r]]<x) ans++;
}
for (int i=bl[l]+1;i<=bl[r]-1;i++){
int t=x-tag[i];
ans+=lower_bound(v[i].begin(),v[i].end(),t)-v[i].begin();
}
return ans;
}
int main() {
scanf("%d%d",&n,&m);
blo=sqrt(n);
for(int i=1;i<=n;i++) {
scanf("%lld",&a[i]);
bl[i]=(i-1)/blo+1;
v[bl[i]].push_back(a[i]);
}
for(int i=1;i<=bl[n];i++) {
sort(v[i].begin(),v[i].end());
}
for (int i=1;i<=m;i++){
scanf("%s",ch);
scanf("%d%d%d",&l,&r,&xx);
if (ch[0]=='C') change(l,r,xx);
else printf("%d\n",search(l,r,xx));
}
}