Loj 6280 数列分块入门 4

链接:https://loj.ac/problem/6280

思路:

多设置一个数组sum去存区间值的和就好了,因为数据范围比较大,需要开long long .

实现代码;

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll M = 1e5+10;
ll sum[M],a[M],tag[M],bl[M],n,block;

void update(ll l,ll r,ll c){
    for(ll i = l;i <= min(bl[l]*block,r);i ++)
        a[i] += c,sum[bl[l]]+=c;
    if(bl[l] != bl[r]){
        for(ll i = (bl[r]-1)*block+1;i <= r;i ++)
            a[i] += c,sum[bl[r]]+=c;
    }
    for(ll i = bl[l]+1;i <= bl[r] -1;i ++)
        tag[i] += c;
}

ll query(ll l,ll r){
    ll ret = 0;
    for(ll i = l;i <= min(bl[l]*block,r);i ++)
        ret += a[i]+tag[bl[l]];
    if(bl[l] != bl[r]){
        for(ll i = (bl[r]-1)*block+1;i <= r;i ++)
            ret += a[i] + tag[bl[r]];
    }
    for(ll i = bl[l]+1;i <= bl[r]-1;i ++)
        ret += sum[i]+tag[i]*block;
    return ret;
}

int main()
{
    ll f,l,r,c;
    cin>>n;
    block = sqrt(n);
    for(ll i = 1;i <= n;i ++) cin>>a[i];
    for(ll i = 1;i <= n;i ++){
        bl[i] = (i-1)/block+1;
        sum[bl[i]]+=a[i];
    }
    for(ll i = 1;i <= n;i ++){
        cin>>f>>l>>r>>c;
        if(f == 0) update(l,r,c);
        else cout<<(query(l,r)%(c+1))<<endl;
    }
    return 0;
}
原文地址:https://www.cnblogs.com/kls123/p/9135147.html