劃重點:(先放一篇大佬的部落格,我就直接劃重點了:
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...