社区讨论

15求调

P3372【模板】线段树 1参与者 2已保存回复 1

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
1 条
当前快照
1 份
快照标识符
@mhj03tq2
此快照首次捕获于
2025/11/03 18:32
4 个月前
此快照最后确认于
2025/11/03 18:32
4 个月前
查看原帖
CPP
#include <iostream>
using namespace std;
#define N 100005

int n, m, a[N];

int d[N], b[N];
void build(int s, int t, int p) {
	if (s == t) {
		d[p] = a[s];
		return ;
	}

	int m = s + ((t - s) >> 1);

	build(s, m, p * 2), build(m + 1, t, p * 2 + 1);

	d[p] = d[p * 2] + d[(p * 2) + 1];
}

void update(int l, int r, int c, int s, int t, int p) {

	if (l <= s && t <= r) {
		d[p] += (t - s + 1) * c, b[p] += c;
		return;
	}

	int m = s + ((t - s) >> 1);

	if (b[p]) {
		d[p * 2] += b[p] * (m - s + 1), d[p * 2 + 1] += b[p] * (t - m);
		b[p * 2] += b[p], b[p * 2 + 1] += b[p];
		b[p] = 0;
	}

	if (l <= m) update(l, r, c, s, m, p * 2);
	if (r > m) update(l, r, c, m + 1, t, p * 2 + 1);

	d[p] = d[p * 2] + d[p * 2 + 1];
}

int get_s(int l, int r, int s, int t, int p) {
	
	if (l <= s && t <= r) return d[p];
	
	int m = s + ((t - s) >> 1);
	if (b[p]) {
		d[p * 2] += b[p] * (m - s + 1), d[p * 2 + 1] += b[p] * (t - m);
		b[p * 2] += b[p], b[p * 2 + 1] += b[p];
		b[p] = 0;
	}
	
	int sum = 0;
	if (l <= m) sum = get_s(l, r, s, m, p * 2);
	if (r > m) sum += get_s(l, r, m + 1, t, p * 2 + 1);
	
	return sum;
}

int main() {
	cin >> n >> m;
	for (int i = 1; i <= n; ++ i) {
		cin >> a[i];
		b[i] = 0;
		d[i] = 0;
	}

	build(1, n, 1);

	while (m --) {
		int op, x, y;
		cin >> op >> x >> y;
		if (op == 1) {
			int k;
			cin >> k;
			update(x, y, k, 1, n, 1);
		} else {
			int sum1 = get_s(x, y, 1, n, 1);
			cout << sum1 << '\n';
		}
	}
	
	return 0;
}

回复

1 条回复,欢迎继续交流。

正在加载回复...