樹狀陣列 模板1 單點修改和區間和

2021-09-11 11:48:38 字數 1400 閱讀 8974

劃重點:(先放一篇大佬的部落格,我就直接劃重點了:

0:樹狀陣列時間修改值和區間和複雜度log(n);用於維護區間和計算區間和。

1:a表示原陣列,c表示樹狀陣列,更新值和更新sum都根據二進位制下標,陣列下標最後從1開始

c[i] = a[i - 2^k + 1] + ..... + a[i]  其中k為i用二進位制表示時的末尾0的個數。根據規律得

c[10100] = c[10010] + c[10001] +a[10100];

c[11000] = c[10100] + c[10110] + c[10111] + a[11000]

總的來說就是從右往左第乙個1變0,後面再從左往右依此加1,1000就變成100,110,111;

2:lowbit()函式

int lowbit(int x)
其中k(末尾0的個數)是樹的高度

第i個節點的父親:i+lowbit(i);

3:updata函式:

void updata(int pos,int k)
例如:updata(2,1);把原來下標為2的值+1,可以理解成a[2]中2變成3,不過是針對樹狀陣列,a[2]還是2;

這個函式也適用於在初始把a陣列轉變成c陣列;

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

updata(i,a[i]);

4:getsum(int x)函式

為了得到從0到x和

s[11000] = c[11000] + c[10000] (s[i]為前i項的和)

s[11100] = c[11100] + c[11000] + c[10000]

11100=2^2+2^3+2^4;對應c中下標11100,11000,10000,(c是對應葉子的和(定義),k對應末尾0個數)

此函式是自頂向下找的

int getsum(int x)

return ans;

}

測試樣例:

#includeusing namespace std;

const int maxn=1010;

int a[maxn],c[maxn],sum[maxn];

int n;

int lowbit(int x)

void updata(int pos,int k)

void init()

int getsum(int x)

return ans;

}int main()

樹狀陣列(單點修改和區間查詢問題)

今天剛學了樹狀陣列,理解還不是很透徹,寫點東西加深理解 記憶 c陣列表示樹狀陣列,a陣列表示普通的陣列 下面用乙個模板題來講解 洛谷 樹狀陣列1 乙個很常見也很簡單的單點修改和區間查詢問題。在學樹狀陣列前有兩種比較常見的解法 單點修改直接修改值,區間查詢時間複雜度是o n 使用字首和優化區間查詢,這...

樹狀陣列 1 單點修改,區間查詢

這是一道模板題。給定數列 a 1 a 2 a n 你需要依次進行 q 個操作,操作有兩類 1 i x 給定 i,x,將 a i 加上 x 2 l r 給定 l,r,求 ri la i 的值 換言之,求 a l a l 1 a r 的值 第一行包含 2 個正整數 n,q,表示數列長度和詢問個數。保證 ...

練習 1 樹狀陣列 模板一(單點修改,區間查詢)

因為是樹狀陣列的第一篇,所以可能會略微加一點樹狀陣列的介紹 其實我也不清楚 直接由題目引入,然後分析。樹狀陣列 1.單點修改,區間查詢 2.區間修改,單點查詢 3.區間修改,區間查詢 description 給定數列a 1 a 2 a n 你需要依次進行 q個操作,操作有兩類 1 i x 給定i,x...