樹狀陣列歸納總結

2021-08-21 19:25:25 字數 1763 閱讀 9234

1,首先它長這個樣子:

由上圖清楚看見:

c1=a1 ;c2=a1+a2;c3=a3;c4=a1+a2+a3+a4;.....依次類推

2,關於lowbit(int x)return x&(-x);

我們從圖上可以看出規律:ci=ai+ai-1....(2^k個a相加,這裡k就是i二進位制末尾0的個數);

比如說奇數(1,3,5....)二進位制末尾都是0個0,所以ci=2^0個a相加的結果;

比如8(二進位制1000)所以是8個a相加;

根據反碼的性質lowbit返回的就是2^k;

3,關於修改

int change(int x,int c)
/*

更新乙個點;我們也需要更新它的根節點;

比如:更新3,lowbit(3)=1是3的子節點數目,3+lowbit(3)就相當於3+右兄弟所有節點數==根節點了。

所以他是更新3再更新4,4的lowbit為4,更新8,最後結束迴圈(看圖)

*/4,關於查詢

int getsun(int x)
/*

對比修改,就是其逆過程;

查詢6,就是求1-6;

先re+c[6],再加上c[4]結束迴圈(看圖);

這個過程就是二進位制最後乙個1補為0的過程,所以時間複雜度就變logn了

*/5,求區間和[l,r],就是利用字首和的思想c[r]-c[l-1];

6,樹狀陣列中的差分約束

比如說有這樣的題目1,2....n的序列,有兩種操作

a:a,b表示[a,b]間序號都要塗一次色;

b,a,問a圖了幾次色

這個題更新時change(a,1),change(b+1,-1);然後直接查詢getsum(a);返回的就是單點資訊

7,二維樹狀陣列

c11=a11;            c12=a11+a12;c13=a13;c14=a11+a12+a13+a14;

c12=a11+a21    a12=a11+a12+a11+a12+a21+a22;.........

和一維一樣

void change(int x,int y,int c)	}}

int getsum(int x,int y)

} return re;

}

8,區間最值的維護(末端插入端點)

8.1加入乙個新節點,就要更新以該節點為根節點的樹的最值。

比如加入節點7,lowbit(7)=1;c[7]=a[7]//a[7]為節點的數值;

比如加入節點8,c[8]為其下的所有節點數值=max(a[8],c7,c[6],c[4]),lowbit(8)=8;

其直接連的節點個數分別是1(節點7),2(5,6)4(1,2,3,4);

比如16,直接連的個數是1,2,4,8;

所以我們更新的時候可以這樣寫:

void change(int r) 

} return re;

}

--r是右其有起第二個節點麼如區間7-8 re=a[8]了,接下來就看7了,7-7re=max(re,re[7])的理由了。

解釋for迴圈,前面已經很多次解釋lowbit(i),就是它應該覆蓋的節點數,如果是r-l>=lowbit(r)大於等於右端點的覆蓋了

那比較c[r]就是了,再縮小範圍。

樹狀陣列總結

樹狀陣列的基本知識已經被各種大牛和菜鳥講到爛了,我就不多說了,下面給出基本操作的 假定原陣列為a 1.n 樹狀陣列b 1.n 考慮靈活性的需要,使用int a傳陣列。define lowbit x x x int sum int a,int x void update int a,int x,int...

樹狀陣列總結

樹狀陣列是對乙個陣列改變某個元素和求和比較實用的資料結構。兩中操作都是o logn 在解題過程中,我們有時需要維護乙個陣列的字首和s i a 1 a 2 a i 但是不難發現,如果我們修改了任意乙個a i s i s i 1 s n 都會發生變化。可以說,每次修改a i 後,調整字首和s在最壞情況下...

樹狀陣列總結

今天學習了一下樹狀陣列,做乙個簡單總結。樹狀陣列可分為兩種操作,1 修改單個點,統計區間和 一般為 向上修改 update1 向下統計 sum1 2 修改區間,統計單個點 一般為向下修改 update2 向上統計 sum2 主要模板如下 int c n int lowbit int x 用於確定區間...