1. 程式人生 > >題解——loj6280 數列分塊入門4 (分塊)

題解——loj6280 數列分塊入門4 (分塊)

cstring ret main turn for string math int lse

分塊維護一個區間和

然後記得更新的時候左邊角塊的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\n",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\n",query(l,r,c+1)); } return 0; }

題解——loj6280 數列分塊入門4 (分塊)