区间操作 区间查询
分块考虑
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+7;
int block,n,q;
int num,belong[maxn];
ll l[maxn],r[maxn],Max[maxn],arr[maxn],lazy[maxn];
vector<int>v[maxn];
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<=num;i++){
for(int j=l[i];j<=r[i];j++){
belong[j]=i;
v[i].push_back(arr[j]);
}
sort(v[i].begin(),v[i].end());
}
}
void update(int x){
v[x].clear();
for(int i=l[x];i<=r[x];i++)v[x].push_back(arr[i]);
sort(v[x].begin(),v[x].end());
}
void change(int x,int y,int c){
int p=belong[ x],q=belong[y];
if(p==q){
for(int i=x;i<=y;i++)arr[i]+=c;
update(p);
}
else{
for(int i=x;i<=r[p];i++)arr[i]+=c;
update(p);
for(int i=l[q];i<=y;i++)arr[i]+=c;
update(q);
for(int i=p+1;i<=q-1;i++)lazy[i]+=c;
}
}
ll ask(int x,int y,ll d){
int p=belong[x],q=belong[y];
ll ans=0;
if(p==q){
ll z=d-lazy[p];
for(int i=x;i<=y;i++)if(arr[i]<z)ans++;
}
else{
for(int i=x;i<=r[p];i++)
if(d>arr[i]+lazy[p])ans++;
for(int i=l[q];i<=y;i++)if(d>arr[i]+lazy[q])ans++;
for(int i=p+1;i<=q-1;i++){
ll z=d-lazy[i];
ans+=lower_bound(v[i].begin(),v[i].end(),z)-v[i].begin();
}
}
return ans;
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%lld",&arr[i]);
build();
for(int i = 1; i <= n; i ++ )
{
int op, l, r, c; scanf("%d%d%d%d", &op, &l, &r, &c);
if(op == 0)
change(l, r, c);
else
printf("%d\n", ask(l,r,c*c));
}
return 0;
}