树状数组模板

 这一部分和线段树基础的功能一样

线段树模板的链接
lowbit(x)覆盖长度
c[x]的父节点t[x + lowbit(x)]

单点修改 区间查询

P3374 【模板】树状数组 1

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 #define int long long
 5 const int maxn = 5e5 + 10;
 6 int n, m, c[maxn];
 7 int lowbit(int x){
 8     return x & - x;
 9 }
10 
11 int ask(int i){
12     int ans = 0;
13     for(;i;i -= lowbit(i))
14         ans += c[i];
15     return ans;
16 }
17 void add(int i,int k){
18     for(;i <= n;i += lowbit(i))
19         c[i] += k;
20 }
21 signed main() {
22     //freopen("in", "r", stdin);
23     ios::sync_with_stdio(0);
24     cin >> n >> m;
25     for (int i = 1; i <= n; i++) {
26         int t;
27         cin >> t;
28         add(i,t);
29     }
30     for (int i = 1; i <= m; i++) {
31         int op, x, y;
32         cin >> op >> x >> y;
33         if (op == 1) add( x, y);
34         else cout << ask(y) - ask(x - 1) << endl;
35     }
36     return 0;
37 }
View Code

区间修改 单点查询

读入的时候,读入到a[]数组里面里面

区间修改:在c[]数组里面改变前缀和的思想,在区间[l,r]上,l + d, r + 1的位置-d;

单点查询:原数组a[x] + (a[x]的增量) ask(x)
P3368 【模板】树状数组 2

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 #define int long long
 4 const int maxn = 5e5 + 5;
 5 int n,m,c[maxn],a[maxn];
 6 int lowbit(int x){
 7     return x & -x;
 8 }
 9 int ask(int i){
10     int ans = 0;
11     for(;i;i -= lowbit(i))
12         ans += c[i];
13     return ans;
14 }
15 
16 void add(int i,int k){
17     for(;i <= n; i += lowbit(i))
18         c[i] += k;
19 }
20 
21 signed main(){
22     //freopen("in","r",stdin);
23     ios::sync_with_stdio(0);
24     cin >> n >> m;
25     for(int i = 1; i <= n; i++)
26         cin >> a[i];
27     while(m--){
28         int op,x,y,d;
29         cin >> op ;
30         if(op == 1) {
31             cin >> x >> y >> d;
32             add(x,d);
33             add(y + 1,-d);
34         }
35         else {
36             cin >> x;
37             cout << a[x] + ask(x) << endl;
38         }
39     }
40     return 0;
41 }
View Code
原文地址:https://www.cnblogs.com/xcfxcf/p/12301572.html