LOJ #6280. 数列分块入门 4

 

 

利用分块,对于整块的再加一个区间和的数组来维护

然后一直 WA,看了看讨论的,要开 long long …… 可能是做法太暴力了吧 

const int N=5e4+5;

    int i,j,k;
    int n,m,t;
    int a[N];
    int L[N],R[N];
    ll bel[N],block,num,sum[N],all[N];

void build()
{
    block=sqrt(n);
    num=n/block; if(n%block) num++;
    for(int i=1;i<=num;i++){
        int l=(i-1)*block+1;
        int r=min(i*block,n*1ll);
        L[i]=l,R[i]=r;
        all[i]=0; sum[i]=0;
        for(int j=l;j<=r;j++) bel[j]=i,sum[i]+=a[j];
    }
}

void update(int l,int r,int w)
{
    int st=bel[l],en=bel[r];
    if(st==en){
        for(int i=l;i<=r;i++) a[i]+=w,sum[st]+=w;
        //sum[st]+=(r-l+1)*w;
    } else{
        for(int i=l;i<=R[st];i++) a[i]+=w,sum[st]+=w;
        //sum[st]+=(R[st]-l+1)*w;
        for(int i=L[en];i<=r;i++) a[i]+=w,sum[en]+=w;
        //sum[en]+=(r-L[en]+1)*w;
        for(int i=st+1;i<=en-1;i++) all[i]+=w;
    }
}

void rep(ll &a,int mod)
{
    a%=mod;
    a+=mod;
    a%=mod;
}

ll query(int l,int r,int w)
{
    ll ans=0;
    int st=bel[l],en=bel[r];
    if(st==en){
        for(int i=l;i<=r;i++){
            ans+=a[i]+all[st];
            rep(ans,w);
        }
    } else{
        for(int i=l;i<=R[st];i++){
            ans+=a[i]+all[st];
            rep(ans,w);
        }
        for(int i=L[en];i<=r;i++){
            ans+=a[i]+all[en];
            rep(ans,w);
        }
        for(int i=st+1;i<=en-1;i++){
            ans+=sum[i]+all[i]*block;
            rep(ans,w);
        }
    }
    return ans%w;
}

int main()
{
    //IOS;
    while(~sd(n)){
        for(int i=1;i<=n;i++) sd(a[i]);
        build();
        while(n--){
            int opt=read(),x=read(),y=read(),w=read();
            if(opt) pll(query(x,y,w+1));
            else update(x,y,w);
        }
    }
    //PAUSE;
    return 0;
}

 

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 酷酷鲨 设计师:CSDN官方博客 返回首页