树状数组
单点修改
void update(int dat[], int i, int j){
while(i <= n){
dat[i] += j;
i += lowbit(i);
}
}
区间求和
int query(int dat[],int k){
int ans = 0;
while(k > 0){
ans += dat[k];
k -= lowbit(k);
}
return ans;
}
#include<iostream>
#include<string.h>
using namespace std;
int n, m;
int dat[50000];
int x;
int lowbit(int k){
return k&(-k);
}
void update(int dat[], int i, int j){
while(i <= n){
dat[i] += j;
i += lowbit(i);
}
}
int query(int dat[],int k){
int ans = 0;
while(k > 0){
ans += dat[k];
k -= lowbit(k);
}
return ans;
}
int main(){
cin >> m;
int cnt = 1;
while(m--){
cin >> n;
memset(dat, 0, sizeof(dat));
for(int i = 1; i <= n ;i++){
cin >> x;
update(dat,i,x);
}
char s[10];
int k, l;
cout << "Case "<<cnt << ":" <<endl;
while(cin >> s){
if(strcmp("End",s) == 0){
break;
}
else{
cin >> k >> l;
if(strcmp(s,"Query") == 0){
cout << query(dat, l) - query(dat, k-1) << endl;
}
else if(strcmp(s,"Add") == 0){
update(dat,k,l);
}
else if(strcmp(s,"Sub") == 0){
update(dat,k,-1*l);
}
else{
break;
}
}
}
cnt++;
}
return 0;
}
2019/10/24总结
树状数组的用途:
1、修改某点的值;
2、求某个区间的和;
lowbit(k): 就是把k的二进制的高位1全部清空;
lowbit(k) = k&(-k);
树状数组的优点:
1、 节省空间(开两倍的原数组就可,线段树需要开四倍原数组);