樹狀陣列的區間修改 查詢

2021-08-19 18:00:22 字數 1975 閱讀 5009

首先看樹狀陣列是用來求字首和比較方便的一種資料結構

sum[i] = sigma a[i] =sum(bit[x])

而區間修改也不難實現

就是引入乙個差分陣列del

del[i]表示對i~n的修改

這樣的話也就是最del[i]求字首和 就能得到i~n的所有修改了

因為i前的每乙個元素的修改都是對後面所有元素的修改

所以當我們統計i~n的修改的時候 我們需要把前面的修改項都累加起來才行

這裡就可以用樹狀陣列統計一下字首和

也就是當我們對區間s~e修改的時候 用del[s]+add 表示對i~n的修改

但是e之後不要修改 所以我們再執行 del[e+1]-add的操作

這樣當我們進行區間修改 單點查詢的時候 就用原始a[i]+sum(del[i])【從1-i的資訊累加之和】即可表示

當我們需要求區間查詢s~e的時候

我們先來看如何求1~i的和

sigma(i) = a[1] + del[1]+ a[2]+ del[1] + del[2] +……+a[i]+del[1]+del[2]+……+del[i]

= a[1]+a[2]+……+a[i] + del[1](i)+del[2] (i-1) +……+del[i] *1

= a[1]+a[2]+……+a[i] + del[1](i-1+1)+del[2] (i-2+1) +……+del[i] *(i-i+1)

= sigma(a[xi]) + sigma(del[ xi ]*( i -xi +1 ) )

= sigma(a[xi]) + sigma(del[ xi ])* ( i +1 ) ) -sigma(del[xi] * xi )

可知 第乙個sigma 是靜態的 可以用字首和預處理出來

第二個sigma: i+1也是不變的 用樹狀陣列統計差分變化 然後求和即可

第三個sigma: 需要另開闢乙個樹狀陣列idel 統計i*del[xi]的字首和

然後當我們修改區間段的時候 對差分陣列del[s]+add 需要同時對 idel[s] + add * s因為最後乙個sigma就是表示要把對差分陣列的每次修改乘上修改的位置/【下標】

然後在求累加和的時候 自然而然的就把sigma(del[xi]*xi)求出來了

經典例題:

poj- 3468 a ****** problem with integers 線段樹區間修改+查詢 | 樹狀陣列的區間修改+查詢

題意就是經典的兩種操作

q s e 表示查詢s到e區間內的總和

c s e add 表示把s到e都加上乙個add

區間內的元素大小1e9

區間長度和查詢次數1e5

分析:

這道題雖然是課裸的線段樹區間修改+查詢+延遲標記

但是繁雜的**不如用實現簡單的樹狀陣列來做

code:

#include

#include

#include

using

namespace

std;

typedef

long

long ll;

const

int maxn = 1e5+10;

ll a[maxn],sum[maxn],del[maxn],idel[maxn];

// 樹狀陣列 區間更新 區間修改

//維護三個樹狀陣列 1 原始樹狀陣列

// 2 差分樹狀陣列 del

// 3 i*del[i] 的樹狀陣列

int n,m;

void update(ll a,int x,int add)

}ll sum(ll a,int x)

return s1;

}int main()

while(m--)

} return

0;}

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

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

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

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

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

說一下差分 現在我們有乙個從小到大的數列a a 1 3 6 8 9 然後還有乙個差分陣列b b 1 2 3 2 1 對應 1,3 1,6 3,8 6,9 8,相信某些同學絕已經看出端倪了.這裡b i a i a i 1 我令a 0 0,故b 1 a 1 int now 0,temp scanf d ...