线段树板子求调
  • 板块学术版
  • 楼主Sukilin
  • 当前回复0
  • 已保存回复0
  • 发布时间2024/10/17 19:31
  • 上次更新2024/10/17 19:31:27
查看原帖
线段树板子求调
959201
Sukilin楼主2024/10/17 19:31

P3372

#include <iostream>
#include <cstdio>
const int N = 1e5 + 7;
int n, m;
int a[N], c[N], t[N];
void build(int l, int r, int p) {
	if(l == r) {
		c[p] = a[l];
		return;
	}
	int m = l + ((r - l) >> 1);
	build(l, m, p * 2);
	build(m + 1, r, p * 2 + 1);
	c[p] = c[p * 2] + c[p * 2 + 1];
}
long long getsum(int l, int r, int L, int R, int p) {
	if(L >= l && R <= r)
		return c[p];
	long long m = L + ((R - L) >> 1);
	if(t[p] && L != R) {
		c[p * 2] += t[p] * (m - L + 1);
		c[p * 2 + 1] += t[p] * (R - m);
		t[p * 2] += t[p];
		t[p * 2 + 1] += t[p];
		t[p] = 0;
	}
	long long sum = 0;
	if(l <= m) sum += getsum(l, r, L, m, p * 2);
	if(r > m) sum += getsum(l, r, m + 1, R, p * 2 + 1);
	return sum;
}
void add(int l, int r, int L, int R, int p, int k) {
	if(L >= l && R <= r) {
		c[p] += k * (R - L + 1);
		t[p] += k;
		return;
	}
	int m = L + ((R - L) >> 1);
	if(t[p] && L != R) {
		c[p * 2] += t[p] * (m - L + 1);
		c[p * 2 + 1] += t[p] * (R - m);
		t[p * 2] += t[p];
		t[p * 2 + 1] += t[p];
		t[p] = 0;
	}
	if(l <= m) add(l, r, L, m, p * 2, k);
	if(r > m) add(l, r, m + 1, R, p * 2 + 1, k);
	c[p] = c[p * 2] + c[p * 2 + 1];
}
int main() {
	std::cin >> n >> m;
	for(int i = 1; i <= n; i++)
		std::cin >> a[i];
	build(1, n, 1);
	int o, x, y, k;
	while(m--) {
		std::cin >> o >> x >> y;
		if(o & 1) {
			std::cin >> k;
			add(x, y, 1, n, 1, k);
		}
		else
			std::cout << getsum(x, y, 1, n, 1) << '\n';
	}
	return 0;
}

后三个点 RE

2024/10/17 19:31
加载中...