学习了树状数组,来简单写一下模板
树状数组主要用于查询 前缀和、区间和、以及点更新!!!
对于点查询而言 普通数组更快,树状数组要求区间和sum2(c[i],c[i-1]);
#include<bits/stdc++.h>
using namespace std;
const int MAXN(1e5+10);
int c[MAXN]; // 树状数组
int a[MAXN]; // 原数组
int n;
// 用于判断树状数组 的 管理范围
int lowbite(int i)
{
return (-i)&i;
}
// 初始化函数
void init()
{
for(int i=1;i<=n;i++)
{
for(int j=i;j<=n;j+=lowbite(j))
c[j]+=a[i];
}
}
// 单点修改函数
void add(int i,int z)
{
// 原数组已经没有用处 所以可以不用修改
// 修改当前节点的父节点 和 当前节点的所有后继节点 的 sum 和值;
a[i]+=z; // 进行点更新 方便用于点查询 ,对于树状数组而言点查询为sum2(c[i]-c[i-1]);
for(;i<=n;i+=lowbite(i))
c[i]+=z;
}
// 求到达某节点的 前缀和函数
int sum1(int i)
{
int sum=0;
for(;i>0;i-=lowbite(i)){
sum+=c[i];
}
return sum;
}
// 求区间和
int sum2(int i,int j)
{
return sum1(j)-sum1(i-1);
}
int main()
{
std::ios::sync_with_stdio(false);
cin>>n;
for(int i=1;i<=n;i++)
cin>>a[i];
init();
int k;
cin>>k;
cout<<"前K个值和为: "<<sum1(k)<<endl;
int x,y;
cin>>x>>y;
cout<<"X 到 Y区间和为:"<<sum2(x,y)<<endl;
}