用分块写的,变量命名可能有些奇怪。
kkk[i]第i个块的左边界
sc03[i]第i个块的右边界
lbd[i]经过排序的数组
ccf[i]未经过排序的数组
#include<bits/stdc++.h>
using namespace std;
struct xzh{
int x,tim,v;
}a[2000001];
struct ldh{
int x,tim,id,v;
}q[1000001];
int n,m,len;
int na,nb,ans[1000001],val[1000001],ccf[1000001],lbd[1000001],id[1000001],kkk[1000001],sc03[1000001],tag[10000001];
bool lcy(int x,int y)
{
return x>y;
}
bool cmpa(xzh x,xzh y)
{
if(x.x==y.x)return x.tim<y.tim;
return x.x<y.x;
}
bool cmpq(ldh x,ldh y)
{
if(x.x==y.x)return x.tim<y.tim;
return x.x<y.x;
}
void update(int l,int r,int x)
{
int L,R;
if(id[l]==id[r])
{
L=kkk[id[l]],R=sc03[id[l]];
for(int i=L;i<=R;++i)
{
if(l<=i&&i<=r)ccf[i]+=x;
lbd[i]=ccf[i];
}
sort(lbd+L,lbd+R+1,lcy);
return;
}
L=kkk[id[l]],R=sc03[id[l]];
for(int i=L;i<=R;++i)
{
if(l<=i)ccf[i]+=x;
lbd[i]=ccf[i];
}
sort(lbd+L,lbd+R+1,lcy);
for(int i=id[l]+1;i<=id[r]-1;i++)
{
tag[i]+=x;
}
L=kkk[id[r]],R=sc03[id[r]];
for(int i=L;i<=R;++i)
{
if(i<=r)ccf[i]+=x;
lbd[i]=ccf[i];
}
sort(lbd+L,lbd+R+1,lcy);
}
int query(int l,int r,int x)
{
int L,R;
int ret=0;
if(id[l]==id[r])
{
for(int i=l;i<=r;++i)
{
if(lbd[i]+tag[id[i]]>=x)++ret;
}
return ret;
}
L=l,R=sc03[id[l]];
for(int i=L;i<=R;++i)
{
if(lbd[i]+tag[id[i]]>=x)++ret;
}
for(int i=id[l]+1;i<=id[r]-1;i++)
{
L=kkk[i],R=sc03[i];
int ans=L-1;
while(L<=R)
{
int mid=(L+R)>>1;
if(lbd[mid]+tag[id[mid]]>=x)
{
ans=mid;
L=mid+1;
}
else
{
R=mid-1;
}
}
ret+=ans-kkk[i]+1;
}
L=kkk[id[r]],R=r;
for(int i=L;i<=R;++i)
{
if(lbd[i]+tag[id[i]]>=x)++ret;
}
return ret;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=n;++i)
{
cin>>val[i];
}
for(int i=1;i<=m;++i)
{
int op;
cin>>op;
if(op==1)
{
int l,r,v;
cin>>l>>r>>v;
a[++na].x=l;a[na].tim=i;a[na].v=v;
a[++na].x=r+1;a[na].tim=i;a[na].v=-v;
}
else
{
int p,y;
cin>>p>>y;
q[++nb].x=p;q[nb].id=nb;q[nb].v=y;q[nb].tim=i;
}
}
sort(a+1,a+1+na,cmpa);sort(q+1,q+1+nb,cmpq);
len=sqrt(m);
for(int i=0;i<=m;++i)
{
id[i]=i/len+1;
}
for(int i=1;(i-1)*len<=m;++i)
{
kkk[i]=(i-1)*len;
sc03[i]=min(i*len-1,m);
}
int now=1;
for(int i=1;i<=nb;++i)
{
while((a[now].x<q[i].x||(a[now].x==q[i].x&&a[now].tim<q[i].tim))&&now<=na)
{
update(a[now].tim,m,a[now].v);
now++;
}
ans[q[i].id]=query(0,q[i].tim-1,q[i].v-val[q[i].x]);
}
for(int i=1;i<=nb;++i)
{
cout<<ans[i]<<endl;
}
return 0;
}