1 . 概念
修改 , 就是从前往后修 , 查寻,就是从后往前查,然后累加 ;
2 . 模板 :
#define lowbit(x) (x&(-x)) // 获取最后一个1
const int N = 5e5+10;
int n , m , s[N] ;
// 向后修
void change(int x , int k){
while(x<=n) s[x] += k , x += lowbit(x) ;
}
// 向前查 , 前缀和
int query(int x){
int t = 0 ;
while(x) t += s[x] , x -= lowbit(x) ;
return t ;
}
3 . 例题
【模板】树状数组 1 - 洛谷
#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define endl '\n'
using namespace std;
#define lowbit(x) (x&(-x)) // 获取最后一个1
const int N = 5e5+10;
int n , m , s[N] ;
// 向后修
void change(int x , int k){
while(x<=n) s[x] += k , x += lowbit(x) ;
}
// 向前查 , 前缀和
int query(int x){
int t = 0 ;
while(x) t += s[x] , x -= lowbit(x) ;
return t ;
}
inline void solve(){
cin >> n >> m ;
for(int i=1;i<=n;i++){
int y ; cin >> y ;
change(i,y) ;
}
while(m--){
int op ; cin >> op ;
if(op==1){
int x , k ; cin >> x >> k ;
change(x,k);
}else{
int x , y ; cin >> x >> y ;
int res = query(y) - query(x-1) ;
cout << res << endl ;
}
}
}
signed main()
{
IOS
int _ = 1;
while(_ --) solve();
return 0;
}
【模板】树状数组 2 - 洛谷
#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define endl '\n'
using namespace std;
#define lowbit(x) (x&(-x)) // 获取最后一个1
const int N = 5e5+10 ;
int n , m , s[N] , a[N] ;
// 向后修
void change(int x , int k){
while(x<=n) s[x] += k , x += lowbit(x) ;
}
// 向前查 , 前缀和
int query(int x){
int t = 0 ;
while(x) t += s[x] , x -= lowbit(x) ;
return t ;
}
inline void solve(){
cin >> n >> m ;
for(int i=1;i<=n;i++){
cin >> a[i] ;
}
while(m--){
int op ; cin >> op ;
if(op==1){
int x , y , k ; cin >> x >> y >> k ;
change(x,k) ; change(y+1,-k) ;
}else{
int x ; cin >> x ;
int res = a[x] + query(x) ;
cout << res << endl ;
}
}
}
signed main()
{
IOS
int _ = 1;
while(_ --) solve();
return 0;
}
4 . 参考 :
C81【模板】树状数组 点修+区查 区修+点查_哔哩哔哩_bilibili