LOJ #6280. 数列分块入门 4

版权声明:欢迎转载 https://blog.csdn.net/yandaoqiusheng/article/details/88605205

题目链接:传送门

区间加法,区间求和

每个块再维护一个sum数组
修改的时候看着改就行了
细节细节

/**
 * @Date:   2019-03-16T20:22:50+08:00
 * @Last modified time: 2019-03-16T20:22:52+08:00
 */
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <complex>
#include <algorithm>
#include <climits>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <iomanip>
#define A 1000010
#define B 2010

using namespace std;
typedef long long ll;
ll f[A], s[A], sq[A];
int n, m, a, b, c, opt, bl[A];
void add(int a, int b, int c) {
    for (int i = a; i <= min(bl[a] * m, b); i++) sq[i] += c, s[bl[a]] += c;
    if (bl[a] != bl[b])
        for (int i = (bl[b] - 1) * m + 1; i <= b; i++) sq[i] += c, s[bl[b]] += c;
    for (int i = bl[a] + 1; i <= bl[b] - 1; i++) f[i] += c;
}
int ask(int a, int b, int c, ll ans = 0) {
    for (int i = a; i <= min(bl[a] * m, b); i++) ans += sq[i] + f[bl[a]]; ans %= c;
    if (bl[a] != bl[b])
        for (int i = (bl[b] - 1) * m + 1; i <= b; i++) ans += sq[i] + f[bl[b]]; ans %= c;
    for (int i = bl[a] + 1; i <= bl[b] - 1; i++) ans += s[i] + f[i] * m;
    return ans % c;
}

int main(int argc, char const *argv[]) {
	scanf("%d", &n); m = sqrt(n);
    for (int i = 1; i <= n; i++) bl[i] = (i - 1) / m + 1;
    for (int i = 1; i <= n; i++) scanf("%d", &sq[i]), s[bl[i]] += sq[i];
    for (int i = 1; i <= n; i++) {
        scanf("%d%d%d%d", &opt, &a, &b, &c);
        if (!opt) add(a, b, c);
        else printf("%d\n", ask(a, b, c + 1));
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/yandaoqiusheng/article/details/88605205