查询复杂度:\(O(logn)\)
区间修改,区间查询

#include<bits/stdc++.h>
using namespace std;
using LL = long long;
struct SegmentTree{
	struct node{
		int l, r;
		LL sum, add;
	};
	vector<int> a;
	vector<node> tr;
	SegmentTree(int n) : a(n + 1), tr(4 * n + 1) {}
	void pull(int u){
		tr[u].sum = tr[2 * u].sum + tr[2 * u + 1].sum;
	}
	void apply(int v, int u){
		tr[v].sum += (tr[v].r - tr[v].l + 1) * tr[u].add;
		tr[v].add += tr[u].add;
	}
	void push(int u){
		apply(2 * u, u);
		apply(2 * u + 1, u);
		tr[u].add = 0;
	}
	void build(int u, int l, int r){
		tr[u] = {l, r};
		if (l == r){
			tr[u].sum = a[r];
			tr[u].add = 0;
			return;
		}
		int mid = (l + r) >> 1;
		build(2 * u, l, mid);
		build(2 * u + 1, mid + 1, r);
		pull(u);
	}
	void modify(int u, int l, int r, LL v){
		if (tr[u].l >= l && tr[u].r <= r){
			tr[u].sum = tr[u].sum + v * (tr[u].r - tr[u].l + 1);
			tr[u].add = tr[u].add + v;
			return;
		}
		push(u);
		int mid = (tr[u].l + tr[u].r) >> 1;
		if (l <= mid) modify(u << 1, l, r, v);
		if (r > mid) modify(u << 1 | 1, l, r, v);
		pull(u);
	}
	void modify(int l, int r, LL v){
		return modify(1, l, r, v);
	}
	LL query(int u, int l, int r){
		if (tr[u].l >= l && tr[u].r <= r) return tr[u].sum;
		push(u);
		int mid = (tr[u].l + tr[u].r) >> 1;
		LL sum = 0;
		if (l <= mid) sum += query(u << 1, l, r);
		if (r > mid) sum += query(u << 1 | 1, l, r);
		return sum;
	}
	LL query(int l, int r){
		return query(1, l, r);
	}
};
int main(){
	ios::sync_with_stdio(false);cin.tie(0);
	int n, m;
	cin >> n >> m;
	SegmentTree t(n);
	for (int i = 1; i <= n; i ++ ){
		cin >> t.a[i];
	}
	t.build(1, 1, n);
	
	while (m -- ){
		int op, l, r;
		cin >> op >> l >> r;
		if (op == 1){
			LL k;
			cin >> k;
			t.modify(l, r, k);
		}
		else{
			cout << t.query(l, r) << "\n";
		}
	}
	return 0;
}

https://www.luogu.com.cn/problem/P3372 区间每个数都加上一个数,查询区间和
https://www.luogu.com.cn/problem/P3373 区间每个数加上或乘上一个数,查询区间和

posted on 2022-02-27 11:35  Hamine  阅读(80)  评论(0编辑  收藏  举报