模板篇 樹狀陣列們(一)

2022-09-06 10:54:16 字數 1623 閱讀 4731

以下文章邏輯混亂,請確保精神正常後再**。

為什麼要搞樹狀陣列???

快。

lowbit是什麼呢???

lowbit(i)指的是i在二進位制表示下最低位的1及其後的所有0組成的值

比如36:在二進位制下是100100,最低位的1我加粗了,代表了4,所以lowbit(36)就是4。。

從圖上可以看出,對於樹狀陣列上的節點,第i個節點控制了(i-lowbit(i),i]的區間。。

比如節點1控制(0,1],節點4控制(0,4],(0是湊的),節點6控制(4,6](其實就是[5,6]啦)……

所以這麼一聯絡就看出樹狀陣列和lowbit密切相關。。

所以很明顯:cn = a(n – 2^k + 1) + … + an

這樣算2^k易得(你要看不懂就不要管為什麼了) lowbit(x)=x&(x^(x-1))①

然後計算機有個非常好的性質叫補碼(就是乙個二進位制數相反數的表示),就是取反再加一。

所以①可簡化為:lowbit(x)=x&-x!!!!真的好簡便呢。。。

好吧,那麼樹狀陣列是怎麼維護上面提到的兩個問題的呢???

好吧,再去看圖。。看圖是有用的。。看到上面無比優美的性質,我們可以用c陣列維護字首和呢。。

沒錯,ci可以儲存1~i的字首和,怎麼求呢?

還記得大明湖畔的lowbit麼?

(怎麼不記得,他費了我半天勁才讓我弄懂呢)

我們讓乙個點不斷的減lowbit,然後把遇到的點的值都加上,就是字首和了!!不信你可以找幾個點蹦一下試試 ,沒錯就是這麼神奇╮(╯_╰)╭……

所以求[l,r]的和,就用[1,r]的和減去[1,l-1]的和就行了~~

//什麼玩意,我用陣列預處理也能做到嘛好像還o(n)呢,你這o(nlogn)算啥嘛。。。

別急,還有修改呢。。你預處理就沒法修改了吧。。。

所以如何修改呢???

單點修改嘛。。看圖。。從i點開始不斷的加lowbit,直到超出範圍為止,單點的維護就搞定了~~ 你可以再找幾個點蹦蹦試試 。

具體的原理基本就這樣,我自己都覺得講得不清楚。。

所以還是上**吧,說不定你們能從**中洞悉這般奧妙。。

#include 

#define gc getchar

class binary_tree1 //讀入優化

inline

void putnum(int x)

binary_tree1(int n) :n(n) //沒任何卵用的建構函式╮(╯_╰)╭

binary_tree1()

void binary_tree1_init() //讀入的初始化

void add(int x, int i)

int sum(int x)

int query(int l, int r)

private:

static

const

int maxn = 500005;

inline

int lb(int x)

int c[maxn], n;

};

模板篇 樹狀陣列們(四)

這是第四篇樹狀陣列了。我們之前講過樹狀陣列的以下幾大作用 單點加區間查 不會的話 區間加單點查 不會的話 區間加區間查 不會的話 然而上面的會不會的無所謂啊。因為上面我們查的都是區間和性質的東西。就是用字首和差分能減出來的東西 而我們今天要做的,是 單點修改,區間查詢最大值 在這裡,我要給大家講一下...

模板篇 樹狀陣列們(四)

這是第四篇樹狀陣列了。我們之前講過樹狀陣列的以下幾大作用 單點加區間查 不會的話 區間加單點查 不會的話 區間加區間查 不會的話 然而上面的會不會的無所謂啊。因為上面我們查的都是區間和性質的東西。就是用字首和差分能減出來的東西 而我們今天要做的,是 單點修改,區間查詢最大值 在這裡,我要給大家講一下...

模板篇 樹狀陣列們(三)

upd 本篇有了乙個更通 hui 俗 se 易 nan 懂的講解,大家可以移步這裡圍觀 使用了latex推柿子,帶給你不一樣的清新體驗 ok,以上兩期稍稍講了一下樹狀陣列的基本功能。當然,把樹狀陣列拉出來不能只有這兩個功能對不對。不然網上都有怎麼把你們忽悠來看嘛 樹狀陣列還是有兩把刷子的 非戰鬥人員...