支援單點修改和區間查詢兩個操作,單次操作o(logn)
tr[x]陣列存的是原陣列在區間 ( x-lowbit(x), x] 上的和
若要將乙個數x變為v,則將x+(-x)+v,即加上v-x
模板如下:
// 建立樹狀陣列
for (int i = 1; i <= n; i ++ ) scanf("%d", &a[i]);
for (int i = 1; i <= n; i ++ ) add(i, a[i]);
//lowbit操作
int lowbit(int x)
//單點修改,x為下標,v為要加的數
void add(int x, int v)
//區間查詢,查詢結果為原陣列區間[1, x]的和,x為下標
int query(int x)
區間[l, r]劃分為[l, mid]和[mid+1, r], mid = $\lfloor $$\frac$$
\rfloor$
單點修改和區間查詢單次操作o(logn)
單點修改:
區間查詢:只返回[l, r]完全包含u區間的值,若沒有完全包含該區間,則繼續遞迴
下標為x的點,父節點為x>>1,左兒子為x<<1,右兒子為x<<1|1
下標從1開始
模板如下:
// 結構體定義線段區間,最多為4n個
struct node
tr[n * 4];
// 用子節點資訊更新當前節點資訊,可能會被省略到程式內部去
void pushup(int u)
//在一段區間上初始化線段樹
void build(int u, int l, int r)
; else
;int mid = l + r >> 1;
build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
pushup(u);
}}//查詢區間[l,r]的和
int query(int u, int l, int r)
//修改,x為要修改點的下標
void modify(int u, int x, int v)
}
演算法學習筆記 樹狀陣列
樹狀陣列 binary indexed trees 是一種可以支援單點修改,較快維護字首和的資料結構。他的實現方式是用乙個陣列維護乙個 樹狀 的結構 如下圖所示 記錄一些區間的區間和,實現快速計算字首和。能看到這裡的同學應該已經對字首和不陌生了。本片部落格就不再贅述 lowbit 操作是表達二進位制...
演算法學習筆記 線段樹
在樹狀陣列那篇部落格中,留下了乙個坑 區間修改區間查詢 樹狀陣列部落格傳送門 今天我們就要來解決這個問題 都很簡單 線段樹是一種可以較快維護滿足區間可加性區間資訊 如 區間和,區間積,區間最大最小等 的資料結構,其基本思想就是二分。注 區間可加性指一些可以通過子區間資訊合併維護的資訊,如區間最大就可...
樹狀陣列 小白演算法學習
在解題過程中,我們有時需要維護乙個陣列的字首和s i a 1 a 2 a i 但是不難發現,如果我們修改了任意乙個a i s i s i 1 s n 都會發生變化。可以說,每次修改a i 後,調整字首和s在最壞情況下會需要o n 的時間。當n非常大時,程式會執行得非常緩慢。因此,這裡我們引入 樹狀陣...