P2801 教主的魔法(分块入门)

两个月之前听yyr学长讲的分块,感觉是个很神奇的暴力,但到现在还是懵的一匹

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+;
int belong[maxn];
int a[maxn];
int b[maxn];
int d[maxn];
int l[maxn];
int r[maxn];
int p[maxn];
int n,q;
int num,block;
void build()//预处理块
{
block=sqrt(n);
num=n/block;
if(n%block)
{
num++;
}
for(int i=;i<=n;i++)
{
belong[i]=(i-)/block+;
b[i]=a[i];
}
for(int i=;i<=num;i++)
{
l[i]=(i-)*block+;
r[i]=i*block;
}
r[num]=n;
for(int i=;i<=num;i++)
{
sort(b+l[i],b+r[i]+);
}
}
void update(int ll,int rr,int w)
{
if(belong[ll]==belong[rr])
{
for(int i=ll;i<=rr;i++)
{
a[i]+=w;
}
for(int i=l[belong[ll]];i<=r[belong[ll]];i++)
{
b[i]=a[i];
}
sort(b+l[belong[ll]],b+r[belong[ll]]+);
}
else
{
for(int i=ll;i<=r[belong[ll]];i++)
{
a[i]+=w;
}
for(int i=l[belong[ll]];i<=r[belong[ll]];i++)
{
b[i]=a[i];
}
sort(b+l[belong[ll]],b+r[belong[ll]]+);
for(int i=l[belong[rr]];i<=rr;i++)
{
a[i]+=w;
}
for(int i=l[belong[rr]];i<=r[belong[rr]];i++)
{
b[i]=a[i];
}
sort(b+l[belong[rr]],b+r[belong[rr]]+);
for(int i=belong[ll]+;i<=belong[rr]-;i++)
{
p[i]+=w;
}
}
}
int ask(int ll,int rr,int c)
{
int ans=;
if(belong[ll]==belong[rr])
{
for(int i=ll;i<=rr;i++)
{
if(a[i]+p[belong[i]]>=c)
{
ans++;
}
}
printf("%d\n",ans);
}
else
{
for(int i=ll;i<=r[belong[ll]];i++)
{
if(a[i]+p[belong[i]]>=c)
{
ans++;
}
}
for(int i=l[belong[rr]];i<=rr;i++)
{
if(a[i]+p[belong[i]]>=c)
{
ans++;
}
}
for(int i=belong[ll]+;i<belong[rr];i++)
{
int l1=l[i],r1=r[i],result=,mid;
while(l1<=r1)
{
mid=(l1+r1)>>;
if(b[mid]+p[i]>=c)
{
r1=mid-;
result=r[i]-mid+;
}
else
{
l1=mid+;
}
}
ans+=result;
}
printf("%d\n",ans);
}
}
int main()
{
int A,B,C;
char ch[];
scanf("%d%d",&n,&q);
for(int i=;i<=n;i++)
{
scanf("%d",&a[i]);
}
build();
while(q--)
{
scanf("%s",ch);
scanf("%d%d%d",&A,&B,&C);
if(ch[]=='A')
{
ask(A,B,C);
}
else
{
update(A,B,C);
}
}
return ;
}
上一篇:Spring boot中使用aop详解


下一篇:关于饿了么在浏览器标签页失去焦点时网页Title改变的实现方法