线段树&树状数组模板
树状数组:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 const int MAXN = 5e5 + 5; 6 7 struct binit { 8 int a[MAXN], n; 9 void modify(int x, int k) { 10 while(x <= n) { 11 a[x] += k; 12 x += (x & -x); 13 } 14 } 15 int query(int x) { 16 int ans = 0; 17 while(x) { 18 ans += a[x]; 19 x -= (x & -x); 20 } 21 return ans; 22 } 23 }t; 24 25 int main () { 26 ios::sync_with_stdio(false); 27 int m, opt, x, y; 28 cin >> t.n >> m; 29 for(int i = 1; i <= t.n; i++) { 30 cin >> x; 31 t.modify(i, x); 32 } 33 while(m--) { 34 cin >> opt >> x >> y; 35 if(opt == 1) t.modify(x, y); 36 else cout << t.query(y) - t.query(x-1) << endl; 37 } 38 return 0; 39 }
线段树:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 typedef long long ll; 6 7 const int MAXN = 1e5+5; 8 9 ll segtree[MAXN << 3], tag[MAXN << 3], a[MAXN]; 10 11 void pushup(int x) { 12 segtree[x] = segtree[x << 1] + segtree[x << 1 | 1]; 13 } 14 15 void pushtag(int x, int l, int r) { 16 tag[x << 1] += tag[x], tag[x << 1 | 1] += tag[x]; 17 int mid = (l + r) >> 1; 18 segtree[x << 1] += tag[x] * (mid - l + 1); 19 segtree[x << 1 | 1] += tag[x] * (r - mid); 20 tag[x] = 0; 21 } 22 23 void build(int x, int l, int r) { 24 if(l < r) { 25 int mid = (l + r) >> 1; 26 build(x << 1, l, mid); 27 build(x << 1 | 1, mid + 1, r); 28 pushup(x); 29 } else segtree[x] = a[l]; 30 } 31 32 ll query(int x, int l, int r, int ql, int qr) { 33 pushtag(x, l, r); 34 if(ql <= l && r <= qr) return segtree[x]; 35 int mid = (l + r) >> 1; ll ans = 0; 36 if(ql <= mid) ans += query(x << 1, l, mid, ql, qr); 37 if(qr > mid) ans += query(x << 1 | 1, mid + 1, r, ql, qr); 38 return ans; 39 } 40 41 void modify(int x, int l, int r, int ql, int qr, ll k) { 42 pushtag(x, l, r); 43 if(ql <= l && r <= qr) { 44 segtree[x] += (r - l + 1) * k; 45 tag[x] += k; 46 } else { 47 int mid = (l + r) >> 1; 48 if(ql <= mid) modify(x << 1, l, mid, ql, qr, k); 49 if(qr > mid) modify(x << 1 | 1, mid+1, r, ql, qr, k); 50 pushup(x); 51 } 52 } 53 54 int main() { 55 int n, m, opt, x, y; ll k; 56 scanf("%d%d", &n, &m); 57 for(int i = 1; i <= n; i++) 58 scanf("%lld", a + i); 59 build(1, 1, n); 60 for(int i = 1; i <= m; i++) { 61 scanf("%d", &opt); 62 if(opt == 1) { 63 scanf("%d%d%lld", &x, &y, &k); 64 modify(1, 1, n, x, y, k); 65 } else { 66 scanf("%d%d", &x, &y); 67 printf("%lld\n", query(1, 1, n, x, y)); 68 } 69 } 70 return 0; 71 }
线段树(动态开点):
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 typedef long long ll; 6 7 struct node { 8 ll data, tag; 9 node *lc, *rc; 10 11 node () { 12 data = 0, lc = rc = NULL; 13 } 14 15 void pushup() { 16 data = 0; 17 if(lc) data += lc->data; 18 if(rc) data += rc->data; 19 } 20 21 void pushtag(int l, int r) { 22 if(!lc) lc = new node; 23 if(!rc) rc = new node; 24 int mid = (l + r) >> 1; 25 lc->data += (mid - l + 1) * tag, lc->tag += tag; 26 rc->data += (r - mid) * tag, rc->tag += tag; 27 tag = 0; 28 } 29 30 } *st = new node; 31 32 void modify(node *cur, int l, int r, int ql, int qr, ll k) { 33 cur->pushtag(l, r); 34 if(ql <= l && r <= qr) { 35 cur->data += (r - l + 1) * k; 36 cur->tag = k; 37 } else { 38 int mid = (l + r) >> 1; 39 if(ql <= mid) modify(cur->lc, l, mid, ql, qr, k); 40 if(qr > mid) modify(cur->rc, mid + 1, r, ql, qr, k); 41 cur->pushup(); 42 } 43 } 44 45 ll query(node *cur, int l, int r, int ql, int qr) { 46 cur->pushtag(l, r); 47 if(ql <= l && r <= qr) { 48 return cur->data; 49 } 50 int mid = (l + r) >> 1; ll ans = 0; 51 if(ql <= mid) ans += query(cur->lc, l, mid, ql, qr); 52 if(qr > mid) ans += query(cur->rc, mid + 1, r, ql, qr); 53 return ans; 54 } 55 56 int main() { 57 int n, m, opt, x, y; ll z; 58 cin >> n >> m; 59 while(m--) { 60 cin >> opt; 61 if(opt == 1) { 62 cin >> x >> y >> z; 63 modify(st, 1, n, x, y, z); 64 } else { 65 cin >> x >> y; 66 cout << query(st, 1, n, x, y) << endl; 67 } 68 } 69 return 0; 70 }