悬关!线段树模板30pts求调。。。
查看原帖
悬关!线段树模板30pts求调。。。
1189047
Creeperawwman楼主2024/9/6 18:28

怎么都只是30pts的代码。。。

#include<bits/stdc++.h>
using namespace std;
int n, q, mod;
long long num[100050];
struct L{
	int left, right;
	long long sum;
	int add, mul;
}t[400050];
long long build(int x, int l, int r) {
	t[x].left = l, t[x].right = r;
	t[x].add = 0;
	t[x].mul = 1;
	if (l == r) {
		t[x].sum = num[l];
		return t[x].sum;
	}
	const int mid = (l + r) / 2;
	t[x].sum = (build(x * 2, l, mid) + build(x * 2 + 1, mid + 1, r)) % mod;
	return t[x].sum;
}
void pushdown(int x) {
	const int ll = t[x * 2].right - t[x * 2].left + 1;
	const int lr = t[x * 2 + 1].right - t[x * 2 + 1].left + 1;
	t[x * 2].sum = (t[x * 2].sum * t[x].mul + t[x].add * ll) % mod;
	t[x * 2 + 1].sum = (t[x * 2 + 1].sum * t[x].mul + t[x].add * lr) % mod;
	t[x * 2].mul = (t[x * 2].mul * t[x].mul) % mod;
	t[x * 2 + 1].mul = (t[x * 2 + 1].mul * t[x].mul) % mod;
	t[x * 2].add = (t[x * 2].add * t[x].mul + t[x].add) % mod;
	t[x * 2 + 1].add = (t[x * 2 + 1].add * t[x].mul + t[x].add) % mod;
	t[x].add = 0, t[x].mul = 1;
}
void pushup(int x) {
	t[x].sum = (t[x * 2].sum + t[x * 2 + 1].sum) % mod;
}
void Mul(int x, int l, int r, int k) {
	if (t[x].left >= l && t[x].right <= r) {
		t[x].mul = (t[x].mul * k) % mod;
		t[x].add = (t[x].add * k) % mod;
		t[x].sum = (t[x].sum * k) % mod;
		return;
	}
	pushdown(x);
	if (t[x * 2].right >= l)	Mul(x * 2, l, r, k);
	if (t[x * 2 + 1].left <= r)	Mul(x * 2 + 1, l, r, k);
	pushup(x);
}
void Add(int x, int l, int r, int k) {
	if (t[x].left >= l && t[x].right <= r) {
		t[x].add = (t[x].add + k) % mod;
		t[x].sum = (t[x].sum + k * (t[x].right - t[x].left + 1)) % mod;
		return;
	}
	pushdown(x);
	if (t[x * 2].right >= l)	Add(x * 2, l, r, k);
	if (t[x * 2 + 1].left <= r)	Add(x * 2 + 1, l, r, k);
	pushup(x);
}
long long rangeSum(int x, int l, int r) {
	if (t[x].left > r || t[x].right < l)	return 0;
	pushdown(x);
	if (t[x].left >= l && t[x].right <= r)	return t[x].sum;
	return (rangeSum(x * 2, l, r) + rangeSum(x * 2 + 1, l, r)) % mod;
}
void solve(int opt) {
	if (opt == 1) {
		int x, y, k;
		scanf("%d %d %d", &x, &y, &k);
		Mul(1, x, y, k);
	}
	if (opt == 2) {
		int x, y, k;
		scanf("%d %d %d", &x, &y, &k);
		Add(1, x, y, k);
	}
	if (opt == 3) {
		int x, y;
		scanf("%d %d", &x, &y);
		printf("%lld\n", rangeSum(1, x, y));
	}
}
void init_solve() {
	scanf("%d %d %d", &n, &q, &mod);
	for (int i = 1; i <= n; i++) {
		scanf("%d", &num[i]);
	}
	build(1, 1, n);
	for (int i = 1; i <= q; i++) {
		int opt;
		cin>>opt;
		solve(opt);
	}
}
int main() {
	init_solve();
	return 0;
}
2024/9/6 18:28
加载中...