树状数组

先贴一个模板代码:html

int lowbit(int i)
{
    return i & -i;
}
//这里的查询以区间和为例
void query(int i)
{
    int ans = 0;
    while(i > 0)
    {
        ans += c[i];
        i -= lowbit(i);
    }
    return ans;
}
//这里的单点更新以加法为例
void update(int i, int val)
{
    while(i <= n)
    {
        c[i] += val;
        i += lowbit(i);
    }
}

我的理解:数组

  几个关键点,首先是 lowbit(i) :指 i 的二进制表示中最低位1及其后续的0组成的数字大小。例如,lowbit(6)中6的二进制表示为110,其最低位1及其后续0组成的二进制数字为10,即十进制的2,因此lowbit(6) = 2。接着是查询和更新操做中,各个区间之间的联系。对于查询操做,要查询的原区间好比是 c[i] ,发现c[i] = c[p] + c[q] + c[r] ,这几个子区间和原区间之间是有联系的,它们的关联就是 i - lowbit(i) == p , p - lowbit(p) == q , q - lowbit(q) == r ,因此查询操做中 i -= lowbit(i)。而更新操做是自底向上更新,和查询的自顶向下查询恰好相反,因此更新操做中 i += lowbit(i)。spa

  树状数组可以解决的问题,线段树几乎都能作,可是树状数组的写法简单,代码简洁code

具体理解细节能够参考这篇博客:http://www.javashuo.com/article/p-hctcmmra-du.htmlhtm

相关文章
相关标签/搜索
本站公众号
   欢迎关注本站公众号,获取更多信息