1. 程式人生 > >樹狀陣列(未完成)

樹狀陣列(未完成)

 

 

(建議邊對著圖邊看解釋)

 

 背景:若線上地修改數列裡某個數的值,其維護【字首和】的複雜度太高

 

樹狀陣列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     }