首先分享我看的网址
树状数组 + 线段树+ 分块原理入门讲解 + 树状数组模版题_哔哩哔哩_bilibili
线段树用分治法;
树状数组模板:
int lowbit(int x){
return x&-x;
}
void (int idx,int v){//idx是加的区域的位置,v是加的值
for(int i=idx;i<=N;i+=lowbit(i)){//因为是加,所以要+lowbit
trr[i]+=v;}
int getsum(int idx){//获得sum的话,是要每个lowbit值去掉最后一个1,直到没1为止;
sum=0;
for(int i=idx;i>=1;i-=lowbit(i))
sum+=trr[i];
}
------------------------------------------------分割线------------------------------------------------------------------------------
#include<iostream>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
using namespace std;
const int maxn = 1e6 + 10;
int N, M;
int arr[maxn];
int trr[maxn];
int lowbit(int x) {
return x & -x;
}
void add(int idx, int v) {
for (int i = idx; i <= N; i += lowbit(i))
trr[i] += v;
}
int getSum(int idx) {
int sum = 0;
for (int i = idx; i >= 1; i -= lowbit(i))
sum += trr[i];
return sum;
}
int main(){
cin >> N >> M;
for (int i = 1; i <= N; i++) {
cin>>arr[i];
}
for (int i = 1; i <= N; i++)//这个是建树
add(i,arr[i]);
while (M--) {
int k, a, b;
cin >> k >> a >> b;
if (k == 0) {
cout << getSum(b) - getSum(a - 1)<<endl;//然后求和是求得整个区域,然后比如求8求的是
}//(1,8]区域的总和所以后面减
else {
add(a, b);
}
}
return 0;
}