轉 樹狀陣列的一些應用

2022-01-15 05:20:41 字數 2104 閱讀 6335

樹狀陣列(bit,binary indexed tree) 

以下**:

1.單點增減+區間求和

思路:c[x]表示該點的元素:sum(x)=c[1]+c[2]+……c[x]

int

arr[maxn];

inline

int sum(int x)

inline

void add(int x,int n)

inline

int query(int x,int y)

2.區間增減+單點查詢

思路:c[x]表示該點元素與左邊元素的差值:num[x]=c[1]+c[2]+……c[x]

int

arr[maxn]

inline

int sum(int x)

inline

void add(int x,int n)

inline

int update(int x,int y,int n)

3.區間增減+區間查詢

思路:c[x]表示該點元素與左邊的差值

sum(sum(c[j],j<=i)i<=x)  =  x*c[1]+(x-1)*c[2]+……+c[x]  =  (x+1)*sum(c[i],i<=x)-sum(i*c[i],i<=x); 

則可以想到用c1[x]維護c[x]的值,c2[x]維護x*c[x]的值

struct

tree_array

int sum(int x)

} t1, t2;

void reset()

void add(int x, int v)

void update(int l, int r, int v) //

[l,r]每個點值都增加v

int sum(int x) //

前x個數的和

int query(int l,int r) //

區間[l,r]的和

};

4.二維:單點增減(add) + 矩形求和(query)+ 矩形增減(update)+ 單點求值(sum)

int

arr[maxn][maxn]

inline

void add(int x,int y,int

v)

inline

int sum(int x,int

y)inline

int query(int l,int b,int r,int

t) inline

void update(int l,int b,int r,int t,int v)

5.單點增減(add) + 立方體求和(query)+ 立方體增減(update) + 單點求值(sum)

int

arr[maxn][maxn][maxn];

inline

int sum(int x,int y,int

z)

inline

void add(int x,int y,int z,int

v)

inline

void update(int x1,int y1,int z1,int x2,int y2,int z2,int

v)

inline

int query(int x1,int y1,int z1,int x2,int y2,int

z2)

6.rmq

inline void

init()

inline

int query(int l,int

r)

else

} return

res;

} inline

void update(int x,int

val)

} }

關於樹狀陣列的一些討論

樹狀陣列用於在log n 的時間複雜度修改與詢問字首 相比線段樹更好寫 常數更小 不過侷限性很大 不能用於維護最大最小值之類的情況 最常用的應用 我用過的 大概有 單點修改區間查詢 區間修改單點查詢 區間修改區間查詢 離散化權值求逆序對 以上內容 洛谷金秋講義 上面已經把樹狀陣列定義以及修改查詢方法...

一些簡單的樹狀陣列題

大意 給定一列數 a i 求滿足下列條件的數對 x,y 的數量 1 xn 與 a i n 是等價的,所以直接將大於n的 a i 賦為 n 可以避免離散化 include include include include include include include include using nam...

一些簡單的樹狀陣列題

大意 給定一列數 a i 求滿足下列條件的數對 x,y 的數量 1 xn 與 a i n 是等價的,所以直接將大於n的 a i 賦為 n 可以避免離散化 include include include include include include include include using nam...