题解——loj6280 数列分块入门4 (分块)
Posted dreagonm
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了题解——loj6280 数列分块入门4 (分块)相关的知识,希望对你有一定的参考价值。
分块维护一个区间和
然后记得更新的时候左边角块的tag不要打错到右边角块
#include <cstdio> #include <algorithm> #include <cstring> #include <cmath> using namespace std; long long sz,num,n,belong[50100],a[50100],sum[50100],tag[50100]; void calbe(int n){ for(int i=1;i<=n;i++) belong[i]=(i-1)/sz+1; } void reset(int x){ sum[x]=0; for(int i=(x-1)*sz+1;i<=min(x*sz,n);i++) sum[x]+=a[i]; } void update(int l,int r,int w){ int xl=belong[l]; int xr=belong[r]; for(int i=l;i<=min(xl*sz,(long long)r);i++){ a[i]+=w; sum[xl]+=w; } if(xl!=xr){ for(int i=(xr-1)*sz+1;i<=r;i++){ a[i]+=w; sum[xr]+=w; } } for(int i=xl+1;i<=xr-1;i++){ tag[i]+=w; } } long long query(int l,int r,int w){ int xl=belong[l]; int xr=belong[r]; long long ans=0; for(int i=l;i<=min(xl*sz,(long long)r);i++) ans=(ans%w+(a[i]+tag[xl])%w)%w; if(xl!=xr){ for(int i=(xr-1)*sz+1;i<=r;i++) ans=(ans%w+(a[i]+tag[xr])%w)%w; } for(int i=xl+1;i<=xr-1;i++) ans=(ans%w+(sum[i]+(tag[i]*sz))%w)%w; return ans; } int main(){ scanf("%lld",&n); sz=sqrt(n); num=n/sz; calbe(n); if(n%sz) num++; for(int i=1;i<=n;i++) scanf("%lld",&a[i]); for(int i=1;i<=num;i++) reset(i); // for(int i=1;i<=num;i++) // printf("%d ",sum[i]); for(int i=1;i<=n;i++){ int opt,l,r,c; scanf("%d %d %d %d",&opt,&l,&r,&c); if(opt==0) update(l,r,c); else printf("%lld ",query(l,r,c+1)); } return 0; }
以上是关于题解——loj6280 数列分块入门4 (分块)的主要内容,如果未能解决你的问题,请参考以下文章