樹狀陣列模版

2021-08-09 07:42:37 字數 1338 閱讀 4065

單點更新,區間求和

#include

#include

using

namespace

std;

const

intmaxn =

1e6+ 1;

inta[maxn

],c[

maxn];

intmaxnum =

1e6;

intlowbit(

intx)

intsum(

intx)

return

res; }

void

add(

intx,

intd)

} intmain()

intl,r;

while

(scanf

("%d%d"

,&l,&r) !=

eof)

return0;

}區間更新,區間求和

設原陣列第

i i

位的值為ai

ai,d

i=ai

−ai−

1 di=ai−ai−1

,則有(這裡認為a0

=0a0=0):

ax=∑

i=1x

diax=∑i=1xdi

所以有: ∑

i=1x

ai=∑

i=1x

∑j=1

idj=

∑i=1

x(x−

i+1)

di∑i=1xai=∑i=1x∑j=1idj=∑i=1x(x−i+1)di

於是我們得到了: ∑

i=1x

ai=(

x+1)

∑i=1

xdi−

∑i=1

xdi×

i ∑i=1xai=(x+1)∑i=1xdi−∑i=1xdi×i

於是我們把原陣列差分後維護兩個樹狀陣列,乙個維護di

di,乙個維護di

×idi×i

。這樣區間求和時可以在兩個樹狀陣列中查詢得到字首和,區間修改時就是差分陣列的修改,每次修改兩個點即可。

void

add(

intx,

inty)

//給差分陣列中的位置x加上y

long

long

sum(

intx)其中c

1ic1i

維護的是di

di,c

2ic2i

維護的是di

×idi×i

樹狀陣列模版

1.一維樹狀陣列 獲得2 k public static int lowbit int i 修改結點 public static void add int i,int value 求和 public static int getsum int i return sum 2.二維樹狀陣列 public...

樹狀陣列模版

原來聽到樹狀陣列這名字感覺很難,很高大上。學了一下發現不難。而且很好。普通的陣列修改某個值耗費為o 1 輸出和為o n 而樹狀陣列為o logn lowbit x 返回的是x二進位制最後一位1的位置 有公式 cn a n a k 1 an 其中 k 為 n 的二進位制表示中從右往左數的 0 的個數 ...

樹狀陣列模版

分析一下上面那個圖看能得出什麼規律 據圖可知 c1 a1,c2 a1 a2,c3 a3,c4 a1 a2 a3 a4,c5 a5,c6 a5 a6,c7 a7,c8 a1 a2 a3 a4 a5 a6 a7 a8,c9 a9,c10 a9 a10,c11 a11.c16 a1 a2 a3 a4 a5...