线段树2 全WA求调 玄关
查看原帖
线段树2 全WA求调 玄关
991533
VecantDK楼主2025/2/7 18:46

打线段树偶遇爆零,拼尽全力无法找出错误。

样例过了。

#include <iostream>
#define ll long long
const int N = 1e5 + 5;
int n, m, p, a[N];
struct Node {
	ll sum, addv, mulv;
} tr[N << 2];
void pushdown(int o, int l, int r) {
	int mid = l + r >> 1;
	tr[o << 1].sum = (tr[o << 1].sum * tr[o].mulv + tr[o].addv * (mid - l + 1)) % p;
	tr[o << 1 | 1].sum = (tr[o << 1 | 1].sum * tr[o].mulv + tr[o].addv * (r - mid)) % p;
	tr[o << 1].mulv = (tr[o << 1].mulv * tr[o].mulv) % p;
	tr[o << 1 | 1].mulv = (tr[o << 1 | 1].mulv * tr[o].mulv) % p; 
	tr[o << 1].addv = (tr[o << 1].addv * tr[o].mulv + tr[o].addv) % p;
	tr[o << 1 | 1].addv = (tr[o << 1 | 1].addv * tr[o].mulv + tr[o].addv) % p;
	tr[o].addv = 0, tr[o].mulv = 1;
}
void pushup(int o) {
	tr[o].sum = tr[o << 1].sum + tr[o << 1 | 1].sum;
}
void build(int o, int l, int r) {
	tr[o].mulv = 1;
	if (l == r) {
		tr[o].sum = a[l] % p;
		return;
	}
	int mid = l + r >> 1;
	build(o << 1, l, mid);
	build(o << 1 | 1, mid + 1, r);
	pushup(o);
}

void add(int o, int l, int r, int x, int y, int k) {
	if (x <= l && r <= y) {
		tr[o].sum = (tr[o].sum + (r - l + 1) * k) % p;
		tr[o].addv = (tr[o].addv + k) % p;
		return;
	}
	int mid = l + r >> 1;
	if (tr[o].addv && l != r) pushdown(o, l, r);
	if (x <= mid) add(o << 1, l, mid, x, y, k);
	if (y > mid)  add(o << 1 | 1, mid + 1, r, x, y, k);
	pushup(o);
}
void mul(int o, int l, int r, int x, int y, int k) {
	if (x <= l && r <= y) {
		tr[o].sum = (tr[o].sum * k) % p;
		tr[o].mulv = (tr[o].mulv * k) % p;
		tr[o].addv = (tr[o].addv * k) % p;
		return;
	}
	int mid = l + r >> 1;
	if (tr[o].mulv != 1 && l != r) pushdown(o, l, r);
	if (x <= mid) mul(o << 1, l, mid, x, y, k);
	if (y > mid)  mul(o << 1 | 1, mid + 1, r, x, y, k);
	pushup(o);
}
ll query(int o, int l, int r, int x, int y) {
	if (x <= l && r <= y) return tr[o].sum;
	int mid = l + r >> 1;
	if (tr[o].addv || tr[o].mulv != 1) pushdown(o, l, r);
	ll sum = 0;
	if (x <= mid) sum = (sum + query(o << 1, l, mid, x, y)) % p;
	if (y > mid)  sum = (sum + query(o << 1 | 1, mid + 1, r, x, y)) % p;
	return sum;
}
int main() {
	scanf("%d%d%d", &n, &m, &p);
	for (int i = 1; i <= n; i++)
		scanf("%d", a + i);
	build(1, 1, n);
	while (m--) {
		int op, x, y;
		ll k;
		scanf("%d%d%d", &op, &x, &y);
		if (op == 1) {
			scanf("%lld", &k);
			k %= p;
			mul(1, 1, n, x, y, k);
		} else if (op == 2) {
			scanf("%lld", &k);
			k %= p;
			add(1, 1, n, x, y, k);
		} else if (op == 3) {
			printf("%lld\n", query(1, 1, n, x, y));
		}
	}
	return 0;
}
2025/2/7 18:46
加载中...