树状数组
简单来说,是一个一维数组,但是可以动态查询前缀和(query()),和在某一个位置上加上一个数(add()),并且两个操作的时间复杂度都是logn。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N = 100010;
int tre[N];//树状数组下标必须从1开始
int n;//树状数组中元素的个数
int lowbi(int x)
{
return x & -x;
}
void add(int x, int v)//在第x个位置加上v
{
for (int i = x; i <= n; i += lowbi(i)) tre[i] += v;
}
int query(int x)//求1-x位置的前缀和
{
int res = 0;
for (int i = x; i; i -= lowbi(i))res += tre[i];
return res;
}
int main()
{
n = 5;
int ex[5] = { 1,2,3,4,5 };
for (int i = 1;i <= 5;i++)
{
add(i, ex[i-1]);//数初始化的时候用add
}
for (int i = 1; i <= 5; i++)
{
cout << tre[i] << endl;
}
cout << query(5) - query(2);//输出第3个位置到第5个位置的和
}