这一部分和线段树基础的功能一样
线段树模板的链接
lowbit(x)覆盖长度
c[x]的父节点t[x + lowbit(x)]
单点修改 区间查询
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 }
区间修改 单点查询
读入的时候,读入到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 }