首页 > 编程语言 > 详细

树状数组

时间:2020-01-22 20:06:04      阅读:81      评论:0      收藏:0      [点我收藏+]

树状数组的本质是将前缀进行拆分维护,\(i\)号节点维护的是原序列上\([i-lowbit(i)+1,i]\)这段区间的信息。

\(lowbit(x)\)表示\(x\)这个数在2进制下从低到高第一个非零位在十进制下的,例如\(lowbit(7)=1,lowbit(8)=8\)

根据计算机补码的性质可得\(lowbit(x)=x\)&\((-x)\)

单点修改:其实就是一个不断找到管辖自己区间的过程,方法就是不断给i自己加上\(lowbit(i)\)跳到下一个管辖自己的区间。

前缀查询:就是把前缀进行拆分,方法就是不断给\(i\)自己扣除\(lowbit(i)\)跳到下一个前缀。

这两个操作的复杂度都是单次\(O(log\) \(n)\)的。

\(code\)

void update(int t,int v)
{
    while(t<=n)
    {
        tree[t]+=v;
        t+=lowbit(t);
    }
}
int query(int t)
{
    int sum=0;
    while(t)
    {
        sum+=tree[t];
        t-=lowbit(t);
    }
    return sum;
}

......

update(x,y);//单点修改,x加上y
query(y)-query(x-1)//区间查询,x到y的和

树状数组还可求逆序对

树状数组

原文:https://www.cnblogs.com/lhm-/p/12229432.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!