简单线段树

#include <bits/stdc++.h>
using namespace std;
using ull = unsigned long long;
using ll  = long long;
const int N = 50010;
int T;
struct node {
	int l, r;
	ll sum, add;
} tr[N * 4];
ll a[N];
inline int ls(int p) {return p << 1;}
inline int rs(int p) {return p << 1 | 1;}
void pushup(int u) {
	tr[u].sum = tr[ls(u)].sum + tr[rs(u)].sum;
}
void pushdown(int u) {
	auto &left = tr[ls(u)], &right = tr[rs(u)], &root = tr[u];
	if (root.add) {
		left.add += root.add; left.sum += (ll)(left.r - left.l + 1) * root.add;
		right.add += root.add; right.sum += (ll)(right.r - right.l + 1) * root.add;
		root.add = 0;
	}
}

void build(int u, int l, int r) {
	if (l == r) tr[u] = {l, r, a[l], 0}; //(ll)?
	else {
		tr[u] = {l, r};
		int mid = l + r >> 1;
		build(ls(u), l, mid);
		build(rs(u), mid + 1, r);
		pushup(u);
	}
}

void modi(int u, int l, int r, int v) {
	if (l <= tr[u].l && r >= tr[u].r) {
		tr[u].sum += (ll)(tr[u].r - tr[u].l + 1) * v;
		tr[u].add += v;
	} else {
		pushdown(u);
		int mid = tr[u].l + tr[u].r >> 1;
		if (l <= mid) modi(ls(u), l, r, v);
		if (r > mid) modi(rs(u), l, r, v);
		pushup(u);
	}
}

ll query(int u, int l, int r) {
	if (l <= tr[u].l && r >= tr[u].r) return tr[u].sum;
	pushdown(u);
	ll v = 0;
	int mid = tr[u].l + tr[u].r >> 1;
	if (l <= mid) v = query(ls(u), l, r);
	if (r > mid) v += query(rs(u), l, r);
	return v;
}
int main() {
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	cin >> T;
	for (int cs = 1; cs <= T; cs ++) {
		memset(a, 0, sizeof(a));
		memset(tr, 0, sizeof(tr));
		int n;
		cin >> n;
		for (int i = 1; i <= n; i ++) cin >> a[i];
		build(1, 1, n);
		string op;
		cout << "Case " << cs << ":\n";
		while (cin >> op && op != "End") {
			if (op == "Add"){
				ll x, y;
				cin >> x >> y;
				modi(1, x, x, y);
			} else if (op == "Sub") {
				ll x, y;
				cin >> x >> y;
				modi(1, x, x, -y);
			} else if (op == "Query") {
				int x, y;
				cin >> x >> y;
				cout << query(1, x, y) << '\n';
			}
		} 
	}
	
	

	return 0;
}

posted @ 2025-10-31 18:02  安德joarith  阅读(8)  评论(0)    收藏  举报