线段树求调,悬关
查看原帖
线段树求调,悬关
726139
残阳如血楼主2023/10/3 21:00

悬 2 关!

#include <iostream>
const int MAX = 1e5 + 10;
typedef long long lint;

lint a[MAX], w[4 * MAX], lzy[4 * MAX];

void pushup(const int u) {
	w[u] = w[u * 2] + w[u * 2 + 1];
}

void maketag(const int u, int len, lint x) {
	lzy[u] += x, w[u] += len * x;
}

void pushdown(const int u, int l, int r) {
	int mid = (l + r) / 2;
	maketag(u * 2, l, mid);
	maketag(u * 2 + 1, mid + 1, r);
	lzy[u] = 0;
}

void build(const int u, int l, int r) {
	if (l == r) {
		w[u] = a[l];
		return ;
	}
	int mid = (l + r) / 2;
	build(u * 2, l, mid);
	build(u * 2 + 1, mid + 1, r);
	pushup(u);
}

lint queryNode(const int u, int l, int r, int p) {
	if (l == r) return w[u];
	int mid = (l + r) / 2;
	pushdown(u, l, r);
	if (mid >= p) return queryNode(u * 2, l, mid, p);
	else return queryNode(u * 2 + 1, mid + 1, r, p);
}

void updateNode(const int u, int l, int r, int p, lint x) {
	if (l == r) {
		w[u] = x;
		return ;
	}
	int mid = (l + r) / 2;
	pushdown(u, l, r);
	updateNode(u * 2, l, mid, p, x);
	updateNode(u * 2 + 1, mid + 1, r, p, x);
	pushup(u);
}

lint query(const int u, int l, int r, int tarl, int tarr) {
	if (tarl > r || tarr < l) return 0;
	if (tarl >= l && tarr <= r) return w[u];
	int mid = (l + r) / 2;
	pushdown(u, l, r);
	return query(u * 2, l, mid, tarl, tarr) + query(u * 2 + 1, mid + 1, r, tarl, tarr);
}

void update(const int u, int l, int r, int tarl, int tarr, lint x) {
	if (tarl > r || tarr < l) return ;
	if (tarl >= l && tarr <= r) {
		maketag(u, r - l + 1, x);
		return ;
	}
	int mid = (l + r) / 2;
	pushdown(u, l, r);
	update(u * 2, l, mid, tarl, tarr, x);
	update(u * 2 + 1, mid + 1, r, tarl, tarr, x);
	pushup(u);
}

int main() {
	int n, m; std::cin >> n >> m;
	for (int i = 1; i <= n; ++i) std::cin >> a[i];
	build(1, 1, n);
	for (lint op, x, y, k; m; --m) {
		std::cin >> op >> x >> y;
		if (op == 1) std::cin >> k, update(1, 1, n, x, y, k);
		else std::cout << query(1, 1, n, x, y) << '\n';
	}
	return 0;
}
2023/10/3 21:00
加载中...