模板篇 樹狀陣列們(三)

2022-09-06 10:51:20 字數 2148 閱讀 2076

upd: 本篇有了乙個更通(hui)俗(se)易(nan)懂的講解, 大家可以移步這裡圍觀~(使用了latex推柿子, 帶給你不一樣的清新體驗~

ok,以上兩期稍稍講了一下樹狀陣列的基本功能。。

當然,把樹狀陣列拉出來不能只有這兩個功能對不對。。。(不然網上都有怎麼把你們忽悠來看嘛)

樹狀陣列還是有兩把刷子的

(非戰鬥人員退散)

今天,我們要講的是:

區間加,區間查

什麼???

許多學過線段樹的人該詫異了吧。。

樹狀陣列還能幹這事?

答案是可以的。。

(○| ̄|_在此%拜一下發明這種做法的神犇orz)

還記得上次我們的c變化成了差分陣列嗎?

樹狀陣列就是擅長求字首和和維護差分資訊~

當然,這次的目標中有兩個區間字樣,所以要開兩個陣列(什麼邏輯嘛……)

其實原因並不是這樣。

我們用乙個差分陣列來儲存相鄰兩個資料的差,這個陣列命名為c1

此時,無論我們在樹狀陣列上怎麼亂搞,原資料的第i個點最後的值(記為a[i]吧)就是求一下c1[i]的總和

(嗯我們上一期的單點查)

對於區間修改,我們採取讓c1[l]加和讓c1[r+1]減的方式(還是差分)

對於區間查詢,我們有ans=sum[r]-sum[l-1](how old are you,差分?)

於是很明顯,最後原陣列中第i個點亂搞一波後的值是sigma(c1[j]) (j=1..i)

你們理清楚沒有。。

理清楚之後,

求1~i的和的時候,仔細看下面:

sum(i)=a[1]+a[2]+...+a[i]

=c1[1]+(c1[1]+c1[2])+...+(c1[1]+c1[2]+...+c1[i])

=i*c1[1]+(i-1)*c1[2]+...+1*c1[i]

=i*(c1[1]+c1[2]+...+c1[i])-(0*c1[1]+1*c1[2]+...+(i-1)*c1[i])

=i*sigma(c1[j])-sigma(c1[j]*(j-1)) (j=1..i)

所以,我們只要同時 維護一下sigma(c1[j])和sigma(c1[j]*(j-1))就行了。。

還記得c1的差分性質麼

所以我們再用乙個陣列c2搞出sigma(c1[j]*(j-1)),在維護c1的時候順手維護一下即可。。

這樣複雜度也不會被改變!!!非常好而且奇妙的性質。。。

sum[i]就照著上面的式子搞就行。。

下面,終於到了**,我有一件事情要說:其實只看**就好,上面講的沒啥用233

**的例子是用的luogu3372的【模板】線段樹 1 (哈哈哈哈,用線段樹的人們!)

題目傳送門:

裡面的資料是要用long long的。。

你們自己看情況改就好了233

而且聽說codevs1082的線段樹練習3也可以用這種方法水過。。

這題的傳送門:

而且碼長空間時間都要優於線段樹哦。。

不過main函式我就不寫了_ (:з」∠) _

而且這兩個題都要開long long而**裡是沒有開的

#include 

#define gc getchar

int getnum()

class binary_tree3

int getnum()

public:

void build(int sum)

}void add(int *r, int x, int i)

int ask(int *r, int x)

void adda(int l, int r, int i)

int query(int l, int r)

};

大概就是這個樣子了。。

- 區間加的話就呼叫adda(l,r,i)就是區間[l,r]加i

- 區間查的話就輸出query(l,r)就是區間[l,r]的區間和了。。

對就是這樣。

模板篇 樹狀陣列們(四)

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

模板篇 樹狀陣列們(四)

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

模板篇 樹狀陣列們(一)

以下文章邏輯混亂,請確保精神正常後再 為什麼要搞樹狀陣列?快。lowbit是什麼呢?lowbit i 指的是i在二進位制表示下最低位的1及其後的所有0組成的值 比如36 在二進位制下是100100,最低位的1我加粗了,代表了4,所以lowbit 36 就是4。從圖上可以看出,對於樹狀陣列上的節點,第...