1. 程式人生 > 其它 >【學習筆記】SE1-1A 樹狀陣列

【學習筆記】SE1-1A 樹狀陣列

< 資料結構 > 樹狀陣列:

概述

樹狀陣列(Binary Indexed Tree,BIT,也稱二叉索引樹)是一個支援元素增加操作與計算區間和操作的較快速的資料結構。

其主要運用了lowbit的思想,構造出瞭如圖的索引樹

lowbit

在如圖的樹中,每一層都代表著第n個元素最低位的1的對應值,

例如6的二進位制110對應的最低位的1對應值是10,即是十進位制下的4,

所以

觀察得

這是因為計算機中負數表示為按位取反後加1的,注:"&"表示按位與,都為1即為一。

拓展到所有正整數上,可以得到

解釋

給出A 陣列, 為元素的序列

我們可以發現,如圖中的樹,如果他是右兒子,那麼它的父親就是,如果他是左兒子就是

先引入C 陣列,其中

可以看出,這代表的是圖中一個橫條(即第i個元素所在橫條包括其下面)的元素和,

(1)我們要求的是區間和,所以就可以用字首和的方法求,不難發現,節點13的字首和(在後面用Si表示字首和)在圖上就是這樣的

即為圖中灰色部分的長條之和,即為

程式碼如下

int ask(int i)
{
    int ans = 0;
    while (i > 0){
        ans += Ci[i];
        i -= lowbit(i);
    }
    return ans;
}

當然,這是求字首和的的程式碼,要求區間(l,r)的和,就用即可

(2)

我們還要增加某一元素的值,因為在圖中C值是相互聯絡的,所以我們發現,要改變某一元素的值,還要改變其祖先節點的C值

這裡也以11為例,修改元素11的值,那麼就得修改如圖

標灰橫條的值,都加上11結點的增量,程式碼如下

void add(int i,int b){
    while (i <= n){
        Ci[i]+=b;
        i += lowbit(i);
    }
}

That's the END