最近遇到到好多线段树问题,但是我还不太想去学线段树,主要是每个题都敲一遍实在是太多辽(╥╯^╰╥),然后我灰溜溜的去补充树状数组各种用法
参考博客:http://www.cnblogs.com/RabbitHu/p/BIT.html
最基础的 单点修改+区间查询
/单点修改+区间查询
void add(int p, int x)//给位置p增加x
{
while(p <= n)
{
a[p] += x;
p += p & -p;
}
}
int ask(int p)//求位置p的前缀和
{
int sum=0;
while(p)
{
sum+=a[p];
p-=p&-p;
}
return sum;
}
int range_ask(int l, int r)//区间求和
{
return ask(r) - ask(l - 1);
}
区间修改+单点查询 这里使用差分思想
d[i]=a[i]−a[i−1] (a[0]=0),则 a[i]=∑ij=d[j],即a[i]等于d[i]的前缀和,所以a[i]可以通过d[i]的前缀和来查询
//区间修改+单点查询
void add(int p,int c)
{
while(p<=n)
{
a[p]+=c;
p+=p&-p;
}
}
int range_add(int l,int r,int c)//区间修改 给区间[l, r]加上c
{
add(l,c);
add(r+1,-c);//多加c的区间减去c
}
int query(int p)//单点查询
{
int sum=0;
while(p)
{
sum+=a[p];
p-=p&-p;
}
return sum;
}
区间修改+区间查询 同样运用差分 可以戳这里http://www.cnblogs.com/RabbitHu/p/BIT.html
//区间修改+区间查询
void add(int p,int c)
{
for(int i=p;i<=n;i+=i&-i)
{
sum1[i]+=c;
sum2[i]+=c*p;
}
}
void range_add(int l,int r)
{
add(l,c);
add(r+1,-c);
}
int query(int p)
{
int sum=0;
for(int i=p;i;i-=i&-i)
sum+=(p+1)sum1[i]-sum2[i];
return sum;
}
int range_qury(int l,int r)
{
retunr query(r)-query(l-1);
}
本文深入探讨了树状数组的多种应用场景,包括单点修改与区间查询、区间修改与单点查询、以及区间修改与区间查询等核心操作。通过具体的代码实现,详细解释了如何利用树状数组解决复杂的数据结构问题,特别适用于处理动态数组的更新和查询需求。
2359

被折叠的 条评论
为什么被折叠?



