身為蒟蒻的我 終於學會了 樹狀陣列 但因為自己還是太蒟蒻 還是糊里糊塗的
所以寫個部落格理理思路
樹狀陣列的數學模型:
樹狀陣列的劃分依據的原理是任何正整數都可以表示為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...