關於樹狀陣列

2021-09-24 23:00:12 字數 1605 閱讀 2153

身為蒟蒻的我 終於學會了 樹狀陣列 但因為自己還是太蒟蒻 還是糊里糊塗的

所以寫個部落格理理思路

樹狀陣列的數學模型:

樹狀陣列的劃分依據的原理是任何正整數都可以表示為2的冪相加的形式

如13=2^3 +2^2 +2^1 進而可以利用這一特性來進行區間求和 設想一下現在乙個序列 長度為n 現在要進行區間求和 若用普通的模擬**或者是字首和來進行求解 那麼它的時間複雜度為o(n) 但是利用樹狀陣列這一特性區間求和 我們可以將複雜度降到o(logn)

下面呈上**注釋

但我還是要把lowbit單獨拿出來講 具體的2進製公式這裡懶得寫了(不會寫)

總之可以抽象理解

i+=lowbit(i)就是不斷為i找父親的過程,也就是找包括i這個節點的分支的過程

假設現在為sum[1]賦值a 那麼就要不斷進行lowbit的操作

二進位制表示1為01

進行完lowbit操作

01+1=010(1與二進位制數的第一位1相加)

也就是找到了包含1的節點2

此時就也要sum[2]+=a

然後不斷以此類推

sum[4]+=a

…現在將區間長度1~8的樹狀數組建好

此時可以對照上面的檢視

1=(001) sum[1]=a[1];

2=(010) sum[2]=a[1]+a[2];

3=(011) sum[3]=a[3];

4=(100) sum[4]=a[1]+a[2]+a[3]+a[4];

5=(101) sum[5]=a[5];

6=(110) sum[6]=a[5]+a[6];

7=(111) sum[7]=a[7];

8=(1000) sum[8]=a[1]+a[2]+a[3]+a[4]+a[5]+a[6]+a[7]+a[8];

那麼在進行區間x~y求和的時候

只需要找出y的字首和減去x-1的字首和即可求出

舉個栗子

求區間2~5的和

此時找到5

然後把sumy+=sum[5]

x-=lowbit(x)向前查詢

101-1=100

對應的是4

sumy+=sum[4]

此時的sumy就已經等於1~5的字首和了

同理求出sum(x-1)

sumy-sum(x-1)即為答案

">#include#includeusing namespace std;

int lowbit(int x)//神奇的lowbit

int n,mu[1000000];

int h;

void add(int x,int y)

}int sum(int a)

return h;

}int main()

cin>>m;//輸入查詢次數

string s;

for(int i=1;i<=m;i++)

else//否則為新增操作

add(x,y);

}

關於樹狀陣列

樹狀陣列 binary indexed tree b.i.t fenwick tree 是乙個查詢和修改複雜度都為log n 的資料結構。主要用於查詢任意兩位之間的所有元素之和,但是每次只能修改乙個元素的值 經過簡單修改可以在log n 的複雜度下進行範圍修改,但是這時只能查詢其中乙個元素的值 如果...

關於樹狀陣列

樹狀陣列的核心在於對一段區間的修改和查詢,巧妙地把陣列用一顆樹表示,從而降低了對陣列的修改和查詢的複雜度。首先引入lowbit int lowbit x 如 x 1 1 0000 0001 1111 1111 1 x 6 6 6 0000 0110 1111 1010 2 總結一下就是 求出某個數二...

關於樹狀陣列的幾點總結

零 樹狀陣列的基本概念 1.概念 2.實現原理 3.特性 1.概念 這是樹狀陣列最基本的應用,也就是支援單點修改區間查詢 時間複雜度均為 2.實現原理 3.具體實現 不停獲取i的二進位制表示中的最後一位1所代表的值 將這個值設為b 在操作過程中 在迴圈中給i增加b之前 向c陣列中下標為i的地方增加x...