0
点赞
收藏
分享

微信扫一扫

LOJ #6280. 数列分块入门 4


题目链接:​​传送门​​

区间加法,区间求和

每个块再维护一个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
#define

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;
}


举报

相关推荐

0 条评论