#include <iostream>
#include <cmath>
#include <algorithm>
#define ll long long
using namespace std;
int n,where[50010],d[50010],cpy[50010],cnt;//where数组储存的是数列中的每个元素所处第i个块
struct block
{
int l;
int r;
ll sum=0,lazytag=0;
}a[200010];
void modify(int l,int r,int c)//修改区间
{
int p=where[l],q=where[r];
if(p==q)//如果左右端点在同一个块
{
for(int i=l;i<=r;i++) d[i]+=c;
for(int i=a[p].l;i<=a[p].r;i++) cpy[i]=d[i];
sort(cpy+a[p].l,cpy+a[p].r+1);
}
else
{
//先处理中间块
for(int i=p+1;i<=q-1;i++) a[i].lazytag+=c;
for(int i=l;i<=a[p].r;i++) d[i]+=c;
for(int i=a[p].l;i<=a[p].r;i++) cpy[i]=d[i];
sort(cpy+a[p].l,cpy+a[p].r+1);
for(int i=a[q].l;i<=r;i++) d[i]+=c;
for(int i=a[q].l;i<=a[q].r;i++) cpy[i]=d[i];
sort(cpy+a[q].l,cpy+a[p].r+1);
}
}
int query(int l,int r,int c)
{
int p=where[l],q=where[r],ans=0;
if(p==q)
{
for(int i=l;i<=r;i++)
if(d[i]+a[p].lazytag<c) ans++;
}
else
{
for(int i=p+1;i<=q-1;i++) ans+=lower_bound(cpy+a[i].l,cpy+a[i].r+1,c-a[i].lazytag)-(cpy+a[i].l);
for(int i=l;i<=a[p].r;i++) if(d[i]+a[p].lazytag<c) ans++;
for(int i=a[q].l;i<=r;i++) if(d[i]+a[q].lazytag<c) ans++;
}
return ans;
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>d[i],cpy[i]=d[i];//输入原数组
int blk_size=sqrt(n);//每个块的大小
for(int i=1;i<=n;i++)
{
where[i]=(i-1)/blk_size+1;
a[where[i]].sum+=d[i];
if((i-1)%blk_size==0) a[++cnt].l=i;
else if((i%blk_size==0)) a[cnt].r=i;
}
for(int i=1;i<=cnt;i++) sort(cpy+a[i].l,cpy+a[i].r+1);
for(int i=1;i<=n;i++)
{
int op,l,r,c;
cin>>op>>l>>r>>c;
if(op==0) modify(l,r,c);
else cout<<query(l,r,c*c)<<endl;
}
return 0;
}
大佬们看看,这段代码是分块求给定区间中有几个数小于某个值的,调破防了