樹狀陣列(未完成)
阿新 • • 發佈:2018-11-10
(建議邊對著圖邊看解釋)
背景:若線上地修改數列裡某個數的值,其維護【字首和】的複雜度太高
樹狀陣列c性質:
1、c[i]的管轄區間以a[i]結尾,從某種意義來說,c[i]與a[i]一一對應
2、c[i]的管轄區間長2^k,k是i的二進位制末尾0的個數
3、父親的管轄區間是兒子區間長度的二倍
4、c[i]的值是a的和,c[i]=a[i-2^k+1]+……+a[i]
主要操作解釋:
1、修改某個元素並一路往上更新
修改a[i],從第一個元素c[i]開始(c[i]一定以a[i]結尾),每次下標i加上其管轄區間長度2^k即得到父親的下標,也就是父親管轄區間的最後一個元素下標
1 //返回2^k 2 static int lowbit(int i){ 3 return i&(-i); 4 } 5 6 static void update(int i,int x){ 7 while (i<=n){ 8 c[i]+=x; 9 i+=lowbit(i); 10 } 11 }
2、求a中前i項的和
累加i前的所有最大子樹的根的值,(每次減小i的2^k的值即可從一顆最大子樹的根直接跳到另一顆最大子樹的根)
1 static int query(int i){ 2 int sum=0; 3 while (i>0){ 4 sum+=c[i]; 5 i-=lowbit(i); 6 } 7 return sum; 8 }