动态开点线段树板子求调
  • 板块学术版
  • 楼主Sukilin
  • 当前回复1
  • 已保存回复1
  • 发布时间2024/11/19 15:53
  • 上次更新2024/11/19 16:02:02
查看原帖
动态开点线段树板子求调
959201
Sukilin楼主2024/11/19 15:53
#include <iostream>
#include <cstdio>
const int N = 1e5 + 7;
int n, m, cnt;
int c[N << 1], lc[N << 1], rc[N << 1], lz[N << 1];
void add(int &p, int L, int R, int x, int k) {
	if(!p) p = ++cnt;
	if(L == R) {
		c[p] += k;
		return;
	}
	int m = (L + R) >> 1;
	if(x < m) add(lc[p], L, m, x, k);
	else add(rc[p], m + 1, R, x, k);
	c[p] = c[lc[p]] + c[rc[p]];
}
int query(int p, int L, int R, int l, int r) {
	if(p == 0) return 0;
	if(L >= l && R <= r) return c[p];
	int m = (L + R) >> 1;
	int ans = 0;
	if(l <= m) ans += query(lc[p], L, m, l, r);
	if(r > m) ans += query(lc[p], m + 1, R, l, r);
	return ans;
}
void range_add(int &p, int L, int R, int l, int r, int k) {
	if(!p) p = ++cnt;
	if(L >= l && R <= r) {
		c[p] += k * (R - L + 1), lz[p] += k;
		return;
	}
	int m = (L + R) >> 1;
	if(lz[p] && L != R) {
		c[lc[p]] += lz[p] * (m - L + 1);
		c[rc[p]] += lz[p] * (R - m);
		lz[lc[p]] += lz[p];
		lz[rc[p]] += lz[p];
		lz[p] = 0;
	}
	if(l <= m) range_add(lc[p], L, m, l, r, k);
	if(r > m) range_add(rc[p], m + 1, R, l, r, k);
	c[p] = c[lc[p]] + c[rc[p]];
}
int main() {
	std::cin >> n >> m;
	int temp = 1;
	int& root = temp;
	for(int i = 1; i <= n; i++) {
		int t;
		std::cin >> t;
		add(root, 1, n, i, t);
	}
	for(int i = 1; i < 2 * n; i++)
		std::cout << c[i] << ' ';
	std::cout << '\n';
	for(int i = 1; i <= m; i++) {
		int o, x, y, k;
		std::cin >> o;
		if(o == 1) {
			std::cin >> x >> y >> k;
			range_add(root, 1, n, x, y, k);
		}
		else {
			std::cin >> x >> y;
			std::cout << query(root, 1, n, x, y) << '\n';
		}
	}
		for(int i = 1; i < 2 * n; i++)
		std::cout << c[i] << ' ';
	return 0;
}
2024/11/19 15:53
加载中...