# bzoj3343: 教主的魔法 分块 标记

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#define MAXN 1010000
using namespace std;
typedef long long LL;
LL a[MAXN],b[1010][1010],mark[1010],n,pos[MAXN],lon,t;
inline LL Min(LL x,LL y)
{
return x<y?x:y;
}
int comp(const int x,const int y)
{
return x>y;
}
inline void work1()
{
LL l,r,w;
scanf("%lld%lld%lld",&l,&r,&w);
LL z=pos[l]+1,y=pos[r]-1;
for(LL i=z;i<=y;i++)
mark[i]+=w;
LL zzh=(pos[l]*lon);
zzh=Min(zzh,r);
for(LL i=l;i<=zzh;i++) a[i]+=w;
zzh=pos[l]*lon;
zzh=Min(zzh,n);
memset(b[pos[r]],0,sizeof(b[pos[r]]));
for(LL i=zzh-lon+1;i<=zzh;i++) b[pos[l]][i%lon+1]=a[i];
sort(b[pos[l]]+1,b[pos[l]]+lon+1);
if(pos[l]!=pos[r])
{
for(LL i=(pos[r]-1)*lon+1;i<=r;i++) a[i]+=w;
zzh=pos[r]*lon;
zzh=Min(zzh,n);
memset(b[pos[r]],0,sizeof(b[pos[r]]));
for(LL i=(pos[r]-1)*lon+1;i<=zzh;i++) b[pos[r]][i%lon+1]=a[i];
sort(b[pos[r]]+1,b[pos[r]]+lon+1);
}
}
inline LL Count(LL p,LL c)
{
LL ans=0,l=1,r=lon;
while(l<=r)
{
LL mid=(l+r)>>1;
if(b[p][mid]+mark[p]<c)
l=mid+1;
else
ans+=(r-mid+1),r=mid-1;
}
return ans;
}
inline void work2()
{
LL l,r,c,ans=0;
scanf("%lld%lld%lld",&l,&r,&c);
LL z=pos[l]+1,y=pos[r]-1;
for(LL i=z;i<=y;i++)
ans+=Count(i,c);
LL zzh=(pos[l]*lon);
zzh=Min(zzh,r);
for(LL i=l;i<=zzh;i++)
if(a[i]+mark[pos[i]]>=c)
ans++;
if(pos[l]!=pos[r])
{
for(LL i=(pos[r]-1)*lon+1;i<=r;i++)
if(a[i]+mark[pos[i]]>=c)
ans++;
}
printf("%lld\n",ans);
}
int main()
{
scanf("%lld",&n);
LL Q;
scanf("%lld",&Q);
lon=(LL)sqrt(n+0.5);
for(LL i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
pos[i]=(i-1)/lon+1;
b[pos[i]][i%lon+1]=a[i];
}
t=pos[n];
for(int i=1;i<=t;i++)
sort(b[i]+1,b[i]+lon+1);
while(Q--)
{
char s[2];
scanf("%s",s);
if(s[0]=='M')work1();
else work2();
}
return 0;
}

posted @ 2017-06-14 11:01  TS_Hugh  阅读(139)  评论(0编辑  收藏  举报