树状数组

来源:互联网 发布:c语言volatile关键字 编辑:程序博客网 时间:2024/05/16 09:10

                                          树状数组

                                 武钢三中   吴豪

【引言】

          在解题过程中,我们有时需要维护一个数组的前缀和S[i]=A[1]+A[2]+...+A[i]。

          但是不难发现,如果我们修改了任意一个A[i],S[i]、S[i+1]...S[n]都会发生变化。

          可以说,每次修改A[i]后,调整前缀和S[]在最坏情况下会需要O(n)的时间。

          当n非常大时,程序会运行得非常缓慢。

          因此,这里我们引入“树状数组”,它的修改与求和都是O(logn)的,效率非常高。

【理论】

          为了对树状数组有个形 象的认识,我们先看下面这张图。

       查看更多精彩图片

          如图所示,红色矩形表示的数组C[]就是树状数组。

          这里,C[i]表示A[i-2^k+1]到A[i]的和,而k则是i在二进制时末尾0的个数,

          或者说是i用2的幂方和表示时的最小指数。

         ( 当然,利用位运算,我们可以直接计算出2^k=i&(i^(i-1)) )

          同时,我们也不难发现,这个k就是该节点在树中的高度,因而这个树的高度不会超过logn。

          所以,当我们修改A[i]的值时,可以从C[i]往根节点一路上溯,调整这条路上的所有C[]即可,

          这个操作的复杂度在最坏情况下就是树的高度即O(logn)。  

          另外,对于求数列的前n项和,只需找到n以前的所有最大子树,把其根节点的C加起来即可。

          不难发现,这些子树的数目是n在二进制时1的个数,或者说是把n展开成2的幂方和时的项数,

          因此,求和操作的复杂度也是O(logn)。

          接着,我们考察这两种操作下标变化的规律:

          首先看修改操作:

          已知下标i,求其父节点的下标。
          我们可以考虑对树从逻辑上转化:

            查看更多精彩图片
         如图,我们将子树向右对称翻折,虚拟出一些空白结点(图中白色),将原树转化成完全二叉树。

         有图可知,对于节点i,其父节点的下标与翻折出的空白节点下标相同。

         因而父节点下标 p=i+2^k  (2^k是i用2的幂方和展开式中的最小幂,即i为根节点子树的规模)

         即  p = i + i&(i^(i-1)) 。

         接着对于求和操作:

         因为每棵子树覆盖的范围都是2的幂,所以我们要求子树i的前一棵树,只需让i减去2的最小幂即可。

         即  p = i - i&(i^(i-1)) 。

        

         至此,我们已经比较详细的分析了树状数组的复杂度和原理。

         在最后,我们将给出一些树状数组的实现代码,希望读者能够仔细体会其中的细节。

【代码】

  求最小幂2^k:


int Lowbit(int t) 

    return t & ( t ^ ( t - 1 ) ); 

             
  求前n项和:


int Sum(int end) 

    int sum = 0; 
    while(end > 0) 
    { 
        sum += in[end]; 
        end -= Lowbit(end); 
    } 
    return sum; 


 对某个元素进行加法操作: 

void plus(int pos , int num) 

    while(pos <= n) 
    { 
          in[pos] += num; 
          pos += Lowbit(pos); 
    } 



原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 手机键盘打出的字是繁体字怎么办 阴阳师协助任务对方接了不做怎么办 wow牧师选错了圣物怎么办 淘宝有几个订单被管控了怎么办 埋线双眼皮一个宽一个窄怎么办 把维D和维C一起吃了怎么办 微信出现当前登录环境异常该怎么办 去麦加朝觐人要出现死亡怎么办 炉石传说偶数骑削弱后怎么办 出于安全和性能方面的原因怎么办 怀孕后不知道拍过好几次牙片怎么办 百度云种子含有非法离线内容怎么办 苹果手机上的迅雷怎么打不开怎么办 微信绑定银行卡收不到验证码怎么办 支付宝转账为什么没验证码怎么办 电视时间比手机慢三分钟怎么办 13岁现在有月经又流鼻血怎么办 酒店给客人把房间开错了怎么办 手机百度云下载的视频分解了怎么办 知道家人被绑架北派传销怎么办 接手前同事的客人无回复怎么办 喝了酒第二天一直吐怎么办 孩子看的鬼片不敢睡觉害怕怎么办 宝宝满月了脸还有点黄怎么办 我情人天天说没时间出去该怎么办 两个月宝宝下体三角区肿了怎么办 夏养的龙猫家里有味怎么办 不小心踩到仓鼠吐血了怎么办 不小心踩到仓鼠的头怎么办 母仓鼠生完孩子特别暴躁怎么办 被仓鼠咬出血怎么办要不要打针 被小仓鼠咬出血了该怎么办 仓鼠咬破手指流血了该怎么办 小仓鼠的手被棉花丝绑住了怎么办 荷兰猪如果不小心撞流血了怎么办 帮同事刷杯子但把杯子弄坏了怎么办 贵宾犬喜欢张开嘴巴跟人玩怎么办 鼻烟放了几天感觉跟受潮一样怎么办 两个月宝宝鼻屎堵住鼻子怎么办 肉包着智齿怎么办洗燥电影完整版 大腿内侧突然长黑痣越来越大怎么办