Description
教主最近学会了一种神奇的魔法,能够使人长高。于是他准备演示给XMYZ信息组每个英雄看。于是N个英雄们又一次聚集在了一起,这次他们排成了一列,被编号为1、2、……、N。
每个人的身高一开始都是不超过1000的正整数。教主的魔法每次可以把闭区间[L, R](1≤L≤R≤N)内的英雄的身高全部加上一个整数W。(虽然L=R时并不符合区间的书写规范,但我们可以认为是单独增加第L(R)个英雄的身高)
CYZ、光哥和ZJQ等人不信教主的邪,于是他们有时候会问WD闭区间 [L, R] 内有多少英雄身高大于等于C,以验证教主的魔法是否真的有效。
WD巨懒,于是他把这个回答的任务交给了你。
【题目分析】
分块。
【代码】
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int a[1000001],b[1000001],n,T,q,cnt=0;
int bel[1000001],L[1001],R[1001],lab[1001];
char op[11];
void up(int k)
{
// printf("UP on %d\n",k);
// if (!lab[k]) return ;
for (int i=L[k];i<=R[k];++i) a[i]+=lab[k],b[i]=a[i];
lab[k]=0;
sort(b+L[k],b+R[k]+1);
}
void query()
{
int l,r,c,ans=0;
scanf("%d%d%d",&l,&r,&c);
if (l>r) swap(l,r);
int ll=bel[l],rr=bel[r];
if (ll==rr)
{
up(ll);
for (int i=l;i<=r;++i) if (a[i]>=c) ans++;
printf("%d\n",ans);
}
else
{
if (ll+1==rr)
{
up(ll);up(rr);
for (int i=l;i<=r;++i)
{
if (a[i]>=c) ans++;
// printf("%d is ok \n",i);
}
printf("%d\n",ans);
}
else
{
up(ll);up(rr);
for (int i=l;i<=R[ll];++i) if (a[i]>=c) ans++;
for (int i=L[rr];i<=r;++i) if (a[i]>=c) ans++;
for (int i=ll+1;i<rr;++i)
{
int ls=L[i],rs=R[i]+1;
while (ls<rs)
{
// printf("Binay %d %d\n",ls,rs);
int mid=(ls+rs)/2;
if (b[mid]>=c-lab[i]) rs=mid;
else ls=mid+1;
}
// printf("%d\n",rs);
ans+=R[i]+1-rs;
// printf("block %d have %d\n",i,rs-R[i]+1);
}
printf("%d\n",ans);
}
}
}
void mod()
{
int l,r,c;
scanf("%d%d%d",&l,&r,&c);
int ll=bel[l],rr=bel[r];
if (ll==rr)
{
for (int i=l;i<=r;++i) a[i]+=c;
up(ll);
}
else
{
for (int i=l;i<=R[ll];++i) a[i]+=c;
for (int i=L[rr];i<=r;++i) a[i]+=c;
up(ll);up(rr);
for (int i=ll+1;i<rr;++i) lab[i]+=c;
}
// for (int i=1;i<=n;++i) printf("%d ",b[i]);
}
int main()
{
scanf("%d%d",&n,&q);
for (int i=1;i<=n;++i) scanf("%d",&a[i]),b[i]=a[i];
T=sqrt(n);
for (int i=1;i<=n;i+=T)
{
cnt++;
L[cnt]=i; R[cnt]=i+T-1;
}
R[cnt]=n;
// for (int i=1;i<=cnt;++i) printf("block %d is from %d to %d\n",i,L[i],R[i]);
for (int i=1;i<=cnt;++i)
for (int j=L[i];j<=R[i];++j)
bel[j]=i;
for (int i=1;i<=cnt;++i) sort(b+L[i],b+R[i]+1);
for (int i=1;i<=q;++i)
{
scanf("%s",op+1);
if (op[1]=='A') query();
else mod();
}
}