樹狀陣列的應用(區間修改,區間查詢,多維樹狀陣列)

2021-08-04 20:30:07 字數 3999 閱讀 9491

14、樹狀陣列

(1)、單點增減+區間求和

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

[cpp]view plain

copy

print?

intarr[maxn];  

inline

intsum(

intx)  

inline

void

add(

intx,

intn)  

(2)、區間增減+單點查詢

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

[cpp]view plain

copy

print?

intarr[maxn]  

inline

intsum(

intx)  

inline

void

add(

intx,

intn)  

(3)、區間增減+區間查詢

思路:c1[x]表示該點元素與左邊的差值,c2[x]表示的是x*c[x]

[cpp]view plain

copy

print?

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]的值

[cpp]view plain

copy

print?

template

<

typename

x>  

struct

tree_array  

x sum(int

x)  

}t1,t2;  

void

reset()  

void

add(

intx,x n)  

void

update(

intl,

intr,

intn)  

x sum(int

x)  

x query(int

l,int

r)  

};  

15、多維樹狀陣列

①單點增減(add) + 矩形求和(query) 

②矩形增減(update) + 單點求值(sum)

[cpp]view plain

copy

print?

intarr[maxn][maxn]  

inline

void

add(

intx,

inty,

intn)   

inline

intsum(

intx,

inty)  

inline

intquery(

intl,

intb,

intr,

intt)   

inline

void

update(

intl,

intb,

intr,

intt,

intn)  

③矩形增減(update)+ 矩形求和(query)

[cpp]view plain

copy

print?

template

<

typename

x>  

class

tree_array  

x sum(int

x,int

y)  

} t1,t2,t3,t4;  

void

add(

intx,

inty,

intn)  

x sum(int

x,int

y)  

public

:  void

init()  

void

update(

intl,

intb,

intr,

intt,

intn)  

x query(int

l,int

b,int

r,int

t)  

};  

④單點增減(add) + 立方體求和(query)

⑤立方體增減(update) + 單點求值(sum)

[cpp]view plain

copy

print?

intarr[maxn][maxn][maxn];  

inline

intsum(

intx,

inty,

intz)  

inline

void

add(

intx,

inty,

intz,

intn)  

inline

void

update(

intx1,

inty1,

intz1,

intx2,

inty2,

intz2,

intn)  

inline

intquery(

intx1,

inty1,

intz1,

intx2,

inty2,

intz2)  

⑥立方體增減(update) + 立方體求和(query)///隨便寫寫……複雜度較高

[cpp]view plain

copy

print?

template

<

typename

x>  

class

tree_array_cube  

void

add(

intx,

inty,

intz,x n)  

}t1,t2,t3,t4,t5,t6,t7,t8;  

void

add(

intx,

inty,

intz,x n)  

x sum(int

x,int

y,int

z)  

public

:  void

init()  

void

update(

intx1,

inty1,

intz1,

intx2,

inty2,

intz2,x n)  

x query(int

x1,int

y1,int

z1,int

x2,int

y2,int

z2)  

};  

16、樹狀陣列—區間最大值

[cpp]view plain

copy

print?

inline

void

init()  

inline

intquery(

intl,

intr)  

else

}  return

res;  

}  inline

void

update(

intx,

intval)  

}  } 

樹狀陣列的應用(區間修改 區間查詢)

樹狀陣列之 區間修改 區間查詢 樹狀陣列的工作是 對一組資料進行快速修改查詢操作 最基本的功能是 單點修改 區間查詢。然後厲害的是 區間修改 單點查詢 用陣列del i 表示原陣列a i a i 1 的值 更厲害的來了。區間修改 區間查詢 用陣列del i 記錄原陣列a i 與前一項和,即del i...

樹狀陣列 區間修改,區間查詢

也許更好的閱讀體驗 好東西,以後可以不打線段樹了 本篇假定讀者都會最基礎的兩種樹狀陣列,即區改單查和單改區查 思考如何維護乙個區間的值,想到了差分 對乙個差分陣列做一次字首和可以得到每個位置的值 再對每個位置累加一下就是乙個區間的值 公式化的講,就是 設差分陣列為 c 則每個位置的值 val i s...

樹狀陣列區間修改區間查詢

題面 首先,我們要推乙個柿子。displaystyle sum a i 把a i 用差分陣列表示出來,就可以寫成 displaystyle sum sum d i 我們考慮一下,每個d i 出現的次數是一定的。那我們可以換一下列舉順序,先列舉d i 在列舉他出現的次數,就可以變成 displayst...