學習筆記 樹狀陣列(整合修改版)

2022-08-22 14:54:10 字數 3265 閱讀 7985

一維樹狀陣列

我學習的版本是這樣的

區間修改:

我們假設sigma(r,i)表示r陣列的前i項和,呼叫一次的複雜度是log2(i)

設原陣列是a[n],差分陣列c[n],c[i]=a[i]-a[i-1],那麼明顯地a[i]=sigma(c,i),如果想要修改a[i]到a[j](比如+v),只需令c[i]+=v,c[j+1]-=v

區間查詢:

在基於樹狀陣列的基礎操作:單點修改、區間查詢上,我們可以這樣操作

首先觀察

a[1]+a[2]+...+a[n]

= (c[1]) + (c[1]+c[2]) + ... + (c[1]+c[2]+...+c[n]) 

= n*c[1] + (n-1)*c[2] +... +c[n]

= n * (c[1]+c[2]+...+c[n]) - (0*c[1]+1*c[2]+...+(n-1)*c[n])    (式子①)

那麼我們就維護乙個陣列c2[n],其中c2[i] = (i-1)*c[i]

每當修改c的時候,就同步修改一下c2,這樣複雜度就不會改變

那麼式子①

=n*sigma(c,n) - sigma(c2,n)

於是我們做到了在o(logn)的時間內完成一次區間和查詢

#include#include

#include

#include

#define n 3010

using

namespace

std;

intn,q,num[n],c1[n],c2[n];

inline

int lowbit(int

x)inline

int add(int *r,int u,int

del)

inline

int sum_(int *r,int

v)inline

void

jimmy()

for(int i=1,type;i<=q;i++)

if(type==2

) }

}int

main()

區間修改 區間查詢

一維樹狀陣列 區間修改 區間查詢(1)

學完本來高高興興

然後一看二維樹狀陣列

那我二維怎麼把乙個點差分成乙個2維的i*j啊

然後就懵逼了

所以這種辦法雖然是正確的,但是不利於推廣

所以接下來介紹一下另一種可以推廣的姿勢的樹狀陣列區間修改+區間查詢的辦法

然後,**一篇dalao的部落格 

orzaireen ,這種樹狀陣列理解完一維就可以輕鬆推廣到二維

#include#include

#include

#include

#define n 3010

using

namespace

std;

struct

bit inline

void add(int x,int

del)

inline

int sum(int

x)};

struct

bit inline

void add(int l,int r,int

del)

inline

void sum(int l,int

r)};

inline

void

jimmy()

intmain()

一維樹狀陣列正確姿勢

#include#include

#include

#include

using

namespace

std;

struct

bit_2d

inline

void add(int x,int y,int

del)

inline

int sum(int x,int y,int

del)

}s;struct

bit_2d

inline

void add(int x,int y,int

del)

inline

void add(int x,int y,int

del)

inline

int sum(int x,int

y) inline

int sum(int a,int b,int c,int

d) }s;

inline

void

jimmy()

intmain()

二維樹狀陣列正確姿勢

x'>δxδx

表示區間[x,

n]'>[x,

n][x,n]

的共同增量. 

利用的差分的思想,對於區間[l,

r]'>[l,

r][l,r]

,每次修改δl,

δr+1

'>δl,

δr+1

δl,δr+1

即可. 

這就解決了區間加的問題.x=

ai′+

∑i=1

xδi'>ax=

a′i+

∑xi=

1δiax=ai′+∑i=1xδi s

x=∑i

=1xa

i=∑i

=1xa

i′+∑

i=1x

(x−i

+1)δ

i=∑i

=1xa

i′+∑

i=1x

δi×(

x+1)

−∑i=

1xδi

×i'>sx=

∑i=1

xai=

∑i=1

xa′i

+∑i=

1x(x

−i+1

)δi=

∑i=1

xa′i

+∑i=

1xδi

×(x+

1)−∑

i=1x

δi×i

sx=∑i=1xai=∑i=1xai′+∑i=1x(x−i+1)δi=∑i=1xai′+∑i=1xδi×(x+1)−∑i=1xδi×i

所以只需維護δi,

δi×i

'>δi,

δi×i

δi,δi×i

的字首和即可.

學習筆記 樹狀陣列

以下 為樹狀陣列最常用的幾個操作 1.low bi t mathrm lowbit function lowbit x longint int64 begin exit x and x end 2.單點修改 procedure replace x,y int64 var i int64 begin ...

樹狀陣列學習筆記

在學習完了線段樹後,聽說樹狀陣列能寫的題,線段樹都能做,所以一直沒有詳細的學習樹狀陣列 直到碰到了一道卡線段樹的題目,因為線段樹運用了很多遞迴,所以常數比較大,容易被卡 現在總結一下樹狀陣列 1 樹狀陣列個人認為就是字首和演變而來的 2 單點更新 當你要更新某個點的值時,你要從下面到上面依次更新過去...

樹狀陣列學習筆記

樹狀陣列 binary index tree,bit 也是很多人心中最簡潔優美的資料結構之一。最簡單的樹狀陣列支援兩種操作,時間複雜度均為 當然,樹狀陣列能維護的不侷限於加法,支援的操作也不止這兩種,甚至有大佬能用樹狀陣列實現平衡樹,但這篇筆記不會深入討論 因為我也還不是很懂 回顧一下,我們說,我們...