0pts 求助
查看原帖
0pts 求助
574745
littlesnake楼主2024/12/24 18:45
# include <bits/stdc++.h>
# define ll long long
# define N 100010

using namespace std;

struct Segment {
	int L, R, len;
	long long sum, add, mul;
} tree[N * 4];
int n, q, op, l, r;
ll x, mod;
                
void build (int root, int L, int R) {
	tree[root].L = L, tree[root].R = R, tree[root].len = R - L + 1;
	tree[root].add = 0, tree[root].mul = 1;
	if (L == R) {
		scanf ("%lld", &tree[root].sum);
		tree[root].sum %= mod;
		return ;
	}
	int mid = (L + R) / 2;
	build (root * 2, L, mid);
	build (root * 2 + 1, mid + 1, R);
	tree[root].sum = (tree[root * 2].sum + tree[root * 2 + 1].sum) % mod;
}

void pushdown (int root) {
	Segment l = tree[root * 2], r = tree[root * 2 + 1];
	l.sum = (l.sum * tree[root].mul % mod + l.len * tree[root].add % mod) % mod;
	r.sum = (r.sum * tree[root].mul % mod + r.len * tree[root].add % mod) % mod;
	l.mul = (l.mul * tree[root].mul) % mod;
	r.mul = (r.mul * tree[root].mul) % mod;
	l.add = (l.add * tree[root].mul % mod + tree[root].add) % mod;
	r.add = (r.add * tree[root].mul % mod + tree[root].add) % mod;
	tree[root].mul = 1, tree[root].add = 0;
}

void Add (int root, int L, int R, long long x) {
	if (L <= tree[root].L && tree[root].R <= R) {
		tree[root].sum = (tree[root].sum + x * tree[root].len) % mod;
		tree[root].add = (tree[root].add + x) % mod;
		return ;
	}
	pushdown (root);
	int mid = (tree[root].L + tree[root].R) / 2;
	if (L <= mid) Add (root * 2, L, R, x);
	if (R >= mid + 1) Add (root * 2 + 1, L, R, x);
	tree[root].sum = (tree[root * 2].sum + tree[root * 2 + 1].sum) % mod;
}

void Mul (int root, int L, int R, long long x) {
	if (L <= tree[root].L && tree[root].R <= R) {
		tree[root].add = (tree[root].add * x) % mod;
		tree[root].mul = (tree[root].mul * x) % mod;
		tree[root].sum = (tree[root].sum * x) % mod;
		return ;
	}
	pushdown (root);
	int mid = (tree[root].L + tree[root].R) / 2;
	if (L <= mid) Mul (root * 2, L, R, x);
	if (R >= mid + 1) Mul (root * 2 + 1, L, R, x);
	tree[root].sum = (tree[root * 2].sum + tree[root * 2 + 1].sum) % mod;
}

ll query (int root, int L, int R) {
	if (L <= tree[root].L && tree[root].R <= R) {
		return tree[root].sum;
	}
	pushdown (root);
	int mid = (tree[root].L + tree[root].R) / 2;
	long long sum = 0;
	if (L <= mid) sum = (sum + query (root * 2, L, R)) % mod;
	if (R >= mid + 1) sum = (sum + query (root * 2 + 1, L, R)) % mod;
	return sum;
}

int main () {

	scanf ("%d%d%lld", &n, &q, &mod);
	build (1, 1, n);
	for (int i = 1; i <= q; i ++) {
		scanf ("%d%d%d", &op, &l, &r);
		if (op == 1) {
			scanf ("%lld", &x);
			Mul (1, l, r, x);
		} else if (op == 2) {
			scanf ("%lld", &x);
			Add (1, l, r, x);
		} else printf ("%lld\n", query (1, l, r));
	}

	return 0;

}

2024/12/24 18:45
加载中...