查询复杂度:\(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 区间每个数加上或乘上一个数,查询区间和