#6280. 数列分块入门 4(区间修改,区间查询)

整理的算法模板合集: ACM模板


在这里插入图片描述
在这里插入图片描述
注意这里需要累加,所以要开long long!

#include <cstdio>
#include <cstring>
#include <cctype>
#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>
#include <set>
using namespace std;
typedef long long ll;

const int N = 50007, M = 500007, INF = 0x3f3f3f3f;

ll read() {
    ll x = 0, f = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9') {
        if (ch == '-')
            f = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9') {
        x = x * 10 + ch - '0';
        ch = getchar();
    }
    return x * f;
}

int n, m, block;
ll sum[N];
int bi[N];
ll add_tag[N];
ll v[N];

void modify(int a, int b, int c)
{
    for(int i = a; i <= min(bi[a] * block, b); ++ i){
        v[i] += c;
        sum[bi[a]] += c;
    }
    if(bi[a] != bi[b]){
        for(int i = (bi[b] - 1) * block + 1; i <= b; ++ i){
            v[i] += c;
            sum[bi[b]] += c;
        }
    }
    for(int i = bi[a] + 1; i <= bi[b] - 1; ++ i){
        add_tag[i] += c;
    }
}

ll query(int a, int b)
{
    ll res = 0;
    for(int i = a; i <= min(bi[a] * block, b); ++ i){
        res += v[i] + add_tag[bi[a]];
    }
    if(bi[a] != bi[b]){
        for(int i = (bi[b] - 1) * block + 1; i <= b; ++ i){
            res += v[i] + add_tag[bi[b]];
        }
    }
    for(int i = bi[a] + 1; i <= bi[b] - 1; ++ i){
        res += sum[i] + block * add_tag[i];//直接算是整个块了,应该是block*add_tag[i]
    }
    return res;
}

int main()
{
    n = read();
    block = sqrt(n);
    for(int i = 1; i <= n; ++i){
        v[i] = read();
    }
    for(int i = 1; i <= n; ++ i){
        bi[i] = (i - 1) / block + 1;
        sum[bi[i]] += v[i];
    }
    for(int i = 1; i <= n; ++ i){
        int op = read(), a = read(), b = read(), c = read();
        if(op == 0){
            modify(a, b, c);
        }
        else if(op == 1){
            printf("%lld\n", query(a, b) % (c + 1));
        }
    }
    return 0;
}

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 撸撸猫 设计师:设计师小姐姐 返回首页