樹狀陣列總結

2021-06-09 06:59:58 字數 1194 閱讀 3603

樹狀陣列的基本知識已經被各種大牛和菜鳥講到爛了,我就不多說了,下面給出基本操作的**。

假定原陣列為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 w)

功能1:sum(x)返回原陣列[1,x]的區間和,update(x,w)將原陣列下標為x的數加上w。

這兩個函式使用o(logn)的時間和o(n)的空間完成單點加減,區間求和的功能。

:功能2接下來做一些公升級,讓樹狀陣列完成區間加減,單點查詢的功能。

考慮將原陣列差分,令d[i]=a[i]-a[i-1],特別地,d[1]=a[1]。

那麼區間[l,r]整體加上k的操作就可以簡單地使用d[l]+=k;d[r+1]-=k來完成了。

此時a[i]=d[1]+..+d[i],所以單點查詢a[i]實際上就是在求d陣列的[1..i]區間和,很容易完成了。

:功能3:下面再公升級一次,完成區間加減,區間求和的功能。

仍然沿用d陣列,考慮a陣列[1,x]區間和的計算。d[1]被累加了x次,d[2]被累加了x-1次,...,d[x]被累加了1次。

因此得到sigma(a[i])=sigma=sigma=(x+1)*sigma(d[i])-sigma(d[i]*i)

所以我們再用樹狀陣列維護乙個陣列d2[i]=d[i]*i,即可完成任務。

poj3468也可以用樹狀陣列搞:實現功能3

#include #include #include #include #define ll long long

#define n 100003

using namespace std;

ll a[n];

ll b[n];

ll c[n];

int n,m;

int lowbit(int x)

ll getsum(ll *a,int p)

void modify(ll *a,int p,ll c)

int main()

else}}

return 0;

}

樹狀陣列總結

樹狀陣列是對乙個陣列改變某個元素和求和比較實用的資料結構。兩中操作都是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 用於確定區間...

樹狀陣列總結

樹狀陣列適合單個元素經常修改而且還反覆要求部分的區間的和的情況。樹狀陣列的所有題線段樹都可以寫,但相對而言程式設計效率和程式執行效率更加高 c只是乙個求和工具 每個c i 最後乙個元素都是a i c i 中有lowbit i 個元素,所以c i 就是 a i lowbit i 1 a i 的和 c的...