樹狀陣列小結(未完待續)

2021-08-04 22:16:39 字數 1637 閱讀 7737

最近剛剛深入到了樹狀陣列是什麼,上年寒假學過,但是當時完全聽不到,最近兩天沉下心來,好好看了下,終於懂這個原理是什麼,感覺並不是很難,而且很好用。

這個圖應該更好理解:

d[1]=a[1];

d[2]=a[1]+a[2];

d[3]=a[3];

d[4]=a[1]+a[2]+a[3]+a[4];

依次類推,6管著5和6  8管著前8項,如果乙個n (偶數)除以2還是乙個偶數那他將是這個n項的和,如果是奇數的那他將管著n-1和第n項這兩項的和

比如說對陣列a,改變某一位的值需o(1),求某個k區間值o(k);

這樣的m次操作是用o(m*k);

顯然資料很大時,效率要差很多;

而樹狀陣列,它改變某一位,或者求某個區間的和,都是o(logn);效率大為改善;

對於上圖怎麼計算區間的和;關鍵是需要幾個函式;

先說樹狀陣列最簡單的用法,修改上面圖中的某個點,並求某段區間的和;

下面介紹幾個函式,用這幾個來處理樹狀陣列的問題。

第乙個函式;

1

int lowbit(intx)2

這個函式主要是用來求的是某個點管轄範圍;

如果是x+=x&(-x);就是得到的改點的父節點的值;比如x=4時;就能得到8;

而x-=x&(-x)的話,就是得到x這個點的管轄區間的下個區間的管轄點;

比如說,x=7,x&(-x)等於1,此時x=6不斷迴圈到0能依次得到 6. 4.;

對於乙個偶數他整除2還是偶數那麼他將是前幾項的和 它進行x&(-x)等於他自己的本身,奇數為1,可以自己手動列印幾組觀察下。

把他們所有的管轄區間正好是1....7;

第二個函式

1

void update(int x,int

num)

28 }

這個函式,是用來修改樹狀陣列的;從當前點開始到它的爸爸,爺爺,這樣的長輩都得需要改變。

如果是一般的演算法只用修改改點就可;但是樹狀陣列必須修改所有改點被管轄的區間;

比如把a陣列的 a[2]減去1,(令n=16);則所有2被管轄的點有4,8,16都應該減去1;

就是呼叫函式 update(2,-1);

第三個函式

1

int getsum(intx)2

9return

s;10 }

這個函式就是求區間和了。。比如getsum(7)的話,就是求a[1]+a[2]+...a[7];

上面是最基本的用法;要學習樹狀陣列必須把上面的過程原理搞明白;

它這樣求和 比如7  會先加7  然後加6 然後加4  7包括自己 ,6包括5和6,4包括前四項,所以這樣就求出來了前七項的和。 

題目大體上可以分為兩種(還有其他的就不多介紹了):

一,每次修改的是乙個點,所求的是關於某段區間;

二,每次修改的是乙個區間,所求的值是關於某個點的;

推薦部落格:

推薦題目:hdu 1556 color the ball   hdu 2689 sort it    hdu 1166  poj2352 stars

相關題解在樹狀陣列專欄有。

hdoj5792 樹狀陣列 未完待續

題意 求有多少種四個數滿足aa ab,ac ad,1 a b n 1 c d n 思路 只要找到兩種情況就成立了。在序列中對於乙個元素在他的後面存在比他大的,還有就是存在對於乙個元素在他的後面比他小的,那麼對於乙個元素的 種情況總和 種情況總和 但是這樣不難發現是有重複的。大哥說有四種可能。前面比他...

nginx 未完待續

yum install y pcre yum install y pcre devel yum install y openssl yum install y openssl devel yum install y zlib yum install y gccyum安裝 yum install y ...

sqlparse(未完待續)

sqlparse.split sql,encoding none sql 包含乙個或多個sql語句的字串 encoding 語句的編碼 可選 sql select from foo select from bar sql list sqlparse.split sql print sql list ...