线段树模板(区间修改,区间查询, 动态开点线段树)
#include <bits/stdc++.h> using namespace std; const int N = 1e5 + 5; int n, m; int w[N]; struct node { int l, r; LL sum, add; }tr[N * 4]; void pushup(int u) { tr[u].sum = tr[u << 1].sum + tr[u << 1 | 1].sum; } void pushdown(int u) { auto &root = tr[u], &left = tr[u << 1], &right = tr[u << 1 | 1]; 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, w[l], 0}; else { tr[u] = {l, r};//不要忘 int mid = l + r >> 1; build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r); pushup(u);//pushup } } void modify(int u, int l, int r, int x) { if (tr[u].l >= l && tr[u].r <= r) { tr[u].sum += (LL)(tr[u].r - tr[u].l + 1) * x; tr[u].add += x; } else { pushdown(u);//modify之间要pushdown int mid = tr[u].l + tr[u].r >> 1; if (l <= mid) modify(u << 1, l, r, x); if (r > mid) modify(u << 1 | 1, l, r, x); pushup(u);//注意pushup } } LL query(int u, int l, int r) { if (tr[u].l >= l && tr[u].r <= r) return tr[u].sum; pushdown(u); int mid = tr[u].l + tr[u].r >> 1; LL ans = 0; if (l <= mid) ans = query(u << 1, l, r); if (r > mid) ans += query(u << 1 | 1, l, r); return ans; } int main() { cin >> n >> m; for (int i = 1; i <= n; i ++) cin >> w[i]; build(1, 1, n); while (m --) { char op; cin >> op; int l, r, x; cin >> l >> r; if (op == 'Q') cout << query(1, l, r) << endl; else { cin >> x; modify(1, l, r, x); } } return 0; }
动态开点线段树不再具有left = u << 1, right = u << 1 | 1的性质,但是不需要离散化就可以处理大范围的数,包括负数
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 const int N = 1e5 + 5; 5 6 int n, m, nidx; 7 int w[N]; 8 struct node { 9 int l, r; 10 LL sum, add; 11 }tr[N << 6]; 12 13 void pushup(int u) { 14 tr[u].sum = tr[tr[u].l].sum + tr[tr[u].r].sum; 15 } 16 17 void pushdown(int u, int l, int r) { 18 if (!tr[u].l) tr[u].l = ++ nidx; 19 if (!tr[u].r) tr[u].r = ++ nidx; 20 21 auto &root = tr[u], &left = tr[tr[u].l], &right = tr[tr[u].r]; 22 int mid = l + r >> 1; 23 if (root.add) { 24 left.add += root.add, left.sum += (LL)(mid - l + 1) * root.add; 25 right.add += root.add, right.sum += (LL)(r - mid) * root.add; 26 root.add = 0; 27 } 28 } 29 30 void modify(int u, int l, int r, int ll, int rr, int x) { 31 if (l >= ll && r <= rr) { 32 int len = r - l + 1; 33 tr[u].sum += (LL)len * x; 34 tr[u].add += x; 35 } 36 else { 37 pushdown(u, l, r);//modify之间要pushdown 38 int mid = l + r >> 1; 39 if (ll <= mid) modify(tr[u].l, l, mid, ll, rr, x); 40 if (rr > mid) modify(tr[u].r, mid + 1, r, ll, rr, x); 41 pushup(u);//注意pushup 42 } 43 } 44 45 LL query(int u, int l, int r, int ll, int rr) { 46 if (l >= ll && r <= rr) return tr[u].sum; 47 if (l > rr || r < ll) return 0; 48 49 pushdown(u, l, r); 50 int mid = l + r >> 1; 51 LL ans = 0; 52 if (l <= mid) ans = query(tr[u].l, l, mid, ll, rr); 53 if (r > mid) ans += query(tr[u].r, mid + 1, r, ll, rr); 54 return ans; 55 } 56 57 int main() { 58 59 cin >> n >> m; 60 for (int i = 1; i <= n; i ++) cin >> w[i], modify(1, -INF, INF, i, i, w[i]); 61 62 while (m --) { 63 char op; cin >> op; 64 int l, r, x; 65 cin >> l >> r; 66 67 if (op == 'Q') cout << query(1, -INF, INF, l, r) << endl; 68 else { 69 cin >> x; 70 modify(1, -INF, INF, l, r, x); 71 } 72 } 73 return 0; 74 }

浙公网安备 33010602011771号