简述
树状数组的更新和查询区间值的和的时间复杂度都是 O(logN), 在频繁查询数组区间值的场景中可以适用.
正常数组的更新时间复杂度是 O(1), 查询区间值的和的时间复杂度为 O(N).
前缀数组的更新时间复杂度是 O(N), 查询区间值的和的时间复杂度为 O(1).
| 数组 | 更新时间复杂度 | 求区间元素和时间复杂度 |
|---|---|---|
| 树状数组 | O(logN) | O(logN) |
| 平常数组 | O(1) | O(N) |
| 前缀数组 | O(N) | O(1) |
分析可看Renference中的链接
c++14环境 代码
#include <vector>
#include <iostream>
#include <math.h>
using namespace std;
/**
简易的树状数组 改变值和查询区间值的时间复杂度为 O(logN) 空间复杂度为 O(1)
接口:
TreeArray(int n=0) 实例化内容大小为n的树状数组
int size() 容器的实际大小
int query(int r) 返回 [0,r] 之间的元素的和
int query(int l, int r) 返回 [l,r] 之间元素的和
void update(int i, int x) 将下标为 i 的元素的值更新为 x (TreeArray[i] = x)
void change(int i, int x) 将下表为 i 的元素的值改变 x (TreeArray[i] += x)
**/
class TreeArray{
public:
TreeArray(int n = 0){
buffer.resize(n+1,0);
}
int size(){
return buffer.size()-1;
}
//查询区间 [0,r] 内元素的和
int query(int r){
if(r < 0 || r >= size()){
cout<<"ERROR: INVALID QUEY PARAMETER r="<<r<<" IN TreeArray::query(int i)"<<endl;
throw 0;
}
int ans = 0;
for(int pos = r+1; pos; pos -= lowbit(pos)){
ans += buffer[pos];
}
return ans;
}
//查询区间 [l,r] 之间元素的和
int query(int l, int r){
if(l < 0 || l >= size() || r < 0 || r >= size() || r < l){
cout<<"ERROR: INVALID QUEY PARAMETER l="<<l<<" r="<<r<<" IN TreeArray::query(int l, int r)"<<endl;
throw 0;
}
return l == 0 ? query(r) : query(r) - query(l-1);
}
//将下标为 i 的元素的值更新为 x (TreeArray[i] = x)
void update(int i, int x){
if(i < 0 || i >= size()){
cout<<"ERROR: INVALID UPDATE PARAMETER i="<<i<<" IN TreeArray::update(int i, int x)"<<endl;
throw 0;
}
x = i == 0 ? x - buffer[1] : x - (query(i) - query(i-1));
change(i,x);
}
//将下表为 i 的元素的值改变 x (TreeArray[i] += x)
void change(int i, int x){
if(i < 0 || i >= size()){
cout<<"ERROR: INVALID UPDATE PARAMETER i="<<i<<" IN TreeArray::change(int i, int x)"<<endl;
throw 0;
}
int bufferSize = buffer.size();
for(int pos = i+1; pos < bufferSize; pos += lowbit(pos)){
buffer[pos] += x;
}
}
private:
int lowbit(int i){
return i & (-i);
}
vector<int> buffer;
};
#include <stdio.h>
using namespace std;
int main()
{
TreeArray temp(100);
for(int i = 0; i < temp.size(); i++){
temp.update(i,i);
}
cout<<temp.query(99)<<endl;
cout<<temp.query(10)<<endl;
cout<<temp.query(1,11)<<endl;
cout<<temp.query(1,12)<<endl;
return 0;
}
程序输出为:
4950 // 0 - 99 的和
55 // 0 - 10 的和
66 // 1 - 11 的和
78 // 1 - 12 的和
浙公网安备 33010602011771号