分块板子
预处理
void init(){
clean();
scanf("%lld",&n);
for(i=1;i<=n;i++)scanf("%lld",&a[i]);
sq=sqrt(n);
for(i=1;i<=sq;i++){
st[i]=n/sq*(i-1)+1;
ed[i]=n/sq*i;
}
ed[sq]=n;
for(i=1;i<=sq;i++){
for(j=st[i];j<=ed[i];j++)belong[j]=i,sum[i]+=a[j];
size[i]=ed[i]-st[i]+1;
}
}
多测清空
void clean(){
memset(sum,0,sizeof sum);//块的区间和
memset(mark,0,sizeof mark);//块标记
memset(st,0,sizeof st);//块的头
memset(ed,0,sizeof ed);//块尾
memset(belong,0,sizeof belong);//各点所在块编号
memset(a,0,sizeof a);//数组
memset(size,0,sizeof size);//各个块的元素总数
}
单点加减
void ad(int x,int y){
a[x]+=y;
sum[belong[x]]+=y;
}
区间求和
int Sum(int l,int r){
int ans=0;
if(belong[l]==belong[r]){
for(int i=l;i<=r;i++)ans+=(a[i]+mark[belong[l]]);
}else{
for(int i=l;i<=ed[belong[l]];i++)ans+=(a[i]+mark[belong[l]]);
for(int i=st[belong[r]];i<=r;i++)ans+=(a[i]+mark[belong[r]]);
for(int i=belong[l]+1;i<belong[r];i++)ans+=(sum[i]+mark[i]*size[i]);
}
return ans;
}
区间修改
void add(int l,int r,int val){
if(belong[l]==belong[r]){
for(int i=l;i<=r;i++){
a[i]+=val;
sum[belong[l]]+=val;
}
}else {
for(int i=l;i<=ed[belong[l]];i++){
a[i]+=val;
sum[belong[l]]+=val;
}
for(int i=st[belong[r]];i<=r;i++){
a[i]+=val;
sum[belong[r]]+=val;
}
for(int i=belong[l]+1;i<belong[r];i++)mark[i]+=val;
}
}
教主的魔法
点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e6+100;
int mark[N],belong[N],st[N],ed[N],n,m,v[N];
int x,y,c;
vector<int>a[N];
void one(int x){
a[x].clear();
for(int i=st[x];i<=ed[x];i++)a[x].push_back(v[i]);
sort(a[x].begin(),a[x].end());
}
void add(int l,int r,int c){
if(belong[l]==belong[r]){
for(int i=l;i<=r;i++)v[i]+=c;
one(belong[l]);
}else{
for(int i=l;i<=ed[belong[l]];i++)v[i]+=c;
one(belong[l]);
for(int i=st[belong[r]];i<=r;i++)v[i]+=c;
one(belong[r]);
for(int i=belong[l]+1;i<belong[r];i++)mark[i]+=c;
}
}
void Sum(int l,int r,int c){
int ans=0;
if(belong[l]==belong[r]){
for(int i=l;i<=r;i++){
if(v[i]+mark[belong[l]]>=c)ans++;
}
}else{
for(int i=l;i<=ed[belong[l]];i++)if(v[i]+mark[belong[l]]>=c)ans++;
for(int i=st[belong[r]];i<=r;i++)if(v[i]+mark[belong[r]]>=c)ans++;
for(int i=belong[l]+1;i<belong[r];i++){
int o=lower_bound(a[i].begin(),a[i].end(),c-mark[i])-a[i].begin();
ans+=(a[i].size()-o);
}
}
printf("%lld\n",ans);
}
signed main(){
scanf("%lld%lld",&n,&m);
for(int i=1;i<=n;i++)scanf("%lld",&v[i]);
int sq=sqrt(n);
for(int i=1;i<=sq;i++){
st[i]=n/sq*(i-1)+1;
ed[i]=n/sq*i;
}
ed[sq]=n;
for(int i=1;i<=sq;i++){
for(int j=st[i];j<=ed[i];j++){
belong[j]=i;
a[i].push_back(v[j]);
}
sort(a[i].begin(),a[i].end());
}
while(m--){
char ch;
scanf(" %s%lld%lld%lld",&ch,&x,&y,&c);
if(ch=='M')add(x,y,c);
else if(ch=='A')Sum(x,y,c);
}
return 0;
}