分块+stl爆草
#include<bits/stdc++.h>
using namespace std;
const int N=50005;
const int K=305;
template<class T>
inline void read(T &x)
{
x=0; int f=1;
static char ch=getchar();
while(!isdigit(ch)) {if(ch=='-') f=-1; ch=getchar();}
while(isdigit(ch)) x=x*10+ch-'0',ch=getchar();
x*=f;
}
inline void write(int x)
{
if(x<0) x=-x,putchar('-');
if(x>9) write(x/10);
putchar(x%10+'0');
}
int n,m,v[N],k,num,b[N],l[K],r[K],f[K];
vector <int> res[K];
inline void rebuild(int id)
{
res[id].clear();
for(int i=l[id];i<=r[id];i++) res[id].push_back(v[i]);
sort(res[id].begin(),res[id].end());
}
inline void add(int x,int y,int z)
{
for(int i=x;i<=min(r[b[x]],y);i++) v[i]+=z;
rebuild(b[x]);
if(b[x]!=b[y])
{
for(int i=l[b[y]];i<=y;i++) v[i]+=z;
rebuild(b[y]);
}
for(int i=b[x]+1;i<=b[y]-1;i++) f[i]+=z;
}
inline int query(int x,int y,int z)
{
int ans=0;
for(int i=x;i<=min(r[b[x]],y);i++) if(v[i]+f[b[x]]<z) ans++;
if(b[x]!=b[y])
for(int i=l[b[y]];i<=y;i++)
if(v[i]+f[b[y]]<z) ans++;
for(int i=b[x]+1;i<=b[y]-1;i++)
{
int temp=z-f[i];
ans+=lower_bound(res[i].begin(),res[i].end(),temp)-res[i].begin();
}
return ans;
}
int main()
{
read(n),read(m);
k=sqrt(n),num=n/k;
if(n%k!=0) num++;
for(int i=1;i<=n;i++) b[i]=(i-1)/k+1,read(v[i]);
for(int i=1;i<=num;i++) l[i]=(i-1)*k+1,r[i]=l[i]+k-1;
r[num]=n;
for(int i=1;i<=num;i++) rebuild(i);
int opt,x,y,z;
while(m--)
{
read(opt),read(x),read(y),read(z);
if(opt==1) add(x,y,z);
if(opt==2) write(query(x,y,z)),putchar('\n');
}
return 0;
}