LOJ #6283. 数列分块入门 7

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

题目链接:传送门
区间加区间乘单点修改

注意改标记就好
别的都一样

#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;
const int mod = 10007;
int n, m, bl[A], add[A], multi[A], sq[A], f[A], opt, a, b, c;
void reset(int x) {
	for (int i = (x - 1) * m + 1; i <= min(x * m, n); i++) sq[i] = (sq[i] * multi[x] % mod + add[x]) % mod;
	add[x] = 0; multi[x] = 1;
}
void addd(int a, int b, int c) {
	reset(bl[a]);
	for (int i = a; i <= min(b, bl[a] * m); i++) sq[i] += c, sq[i] %= mod;
	if (bl[a] != bl[b]) {
		reset(bl[b]);
		for (int i = min(b, (bl[b] - 1) * m + 1); i <= b; i++) sq[i] += c, sq[i] %= mod;
	}
	for (int i = bl[a] + 1; i <= bl[b] - 1; i++) add[i] += c, add[i] %= mod;
}
void multii(int a, int b, int c) {
	reset(bl[a]);
	for (int i = a; i <= min(b, bl[a] * m); i++) sq[i] *= c, sq[i] %= mod;
	if (bl[a] != bl[b]) {
		reset(bl[b]);
		for (int i = min(b, (bl[b] - 1) * m + 1); i <= b; i++) sq[i] *= c, sq[i] %= mod;
	}
	for (int i = bl[a] + 1; i <= bl[b] - 1; i++) add[i] *= c, add[i] %= mod, multi[i] *= c, multi[i] %= mod;
}

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

猜你喜欢

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