資料結構學習 分塊與樹狀陣列

2022-08-09 10:06:15 字數 2448 閱讀 3418

分塊與樹狀陣列均在區間問題上有重要的應用

emm分塊效率上不如樹狀陣列,但是思路比較好想

先說分塊:

將n個數的序列分為sqrt(n)塊,預處理每塊資料的資訊以加快後續對區間資訊的查詢

const

int maxn = 5e5 + 50

;int

sum[maxn],a[maxn],l[maxn],r[maxn],belong[maxn];

intblock,num;

void

build()

}

**中的全域性變數有這些是需要預處理的:sum[i]表示第i塊資料的和(也可是異或和、乘積這類,一樣的)

a[i]為第i個資料,l[i],r[i]分別為第i塊的左右端點下標,belong[i]儲存第i個數所屬的分塊

預處理過後,貼上單點修改/更新和區間查詢的**:

inline void update(int x, int

y)inline

int query(int x, int

y)

for(int i = x; i <= r[belong[x]]; i++)

ans +=a[i];

for(int i = belong[x] + 1; i < belong[y]; i++)

ans +=sum[i];

for(int i = l[belong[y]]; i <= y; i++)

ans +=a[i];

return

ans;

}

其中對單點進行資料更新只需將陣列a中資料改變,再將下標為x所屬的塊的總和增加y即可

而查詢區間[x,y]的和,分塊這裡採用的是暴力求和

1.當x,y在同一塊中時,遍歷求和

2.當x,y不在同一塊,遍歷求和x到x所屬塊的右邊界,再加上sum[x+1]到sum[y-1],再遍歷求和y所屬塊的左邊界到y

時間複雜度均為o(sqrt(n)) 單點修改為o(1)

ok繼續:

樹狀陣列,用途較分塊而言應用的更加廣泛,單點修改與區間和的查詢效率均為對數複雜度

也可用於同時需要進行單點查詢和區間修改/區間查詢和區間修改的情況

樹狀陣列長這樣:

用乙個陣列tree來輔助原陣列a的儲存(也就是我們建立的這個樹狀陣列)

其中tree[i] = a[i - 2^k + 1] +……+ a[i] (k為i的二進位制位末尾連續0的個數, 2^k有專門的乙個名字:lowbit)

順便:lowbit(i) = i&-i (主要是利用了二進位制數在計算機內儲存的性質,我沒深究。)

ok,這是建樹狀陣列的乙個基礎的式子。

當我們需要來對序列中某個值進行更新時(改變/加減數之類的),比如a[i] += k

就需要改變tree陣列內所有與a[i]相關的值,即tree[i+2^k],tree[(i+2^k) + 2^k']……

依此反覆迭代更改i的值並更新即可

接下來是求和 前i項的和sumi = c[i] + c[i - 2^k] + c[(i - 2^k) - 2^k']…

【ps:至於樹狀陣列為啥這麼定義k,為什麼sum的計算是這樣的,其實我並沒有搞得很清楚,我個人感覺樹狀陣列這個東西更像是強行利用了二進位制人造出來的乙個方便使用的毫無數學美感的資料結構,反正我學的時候感覺到很讓人不理解,各種資料也沒有講明白定義的依據。】

知道如何維護和查詢後就可以用了。

附上**:

const

int maxn = 5e5 + 5

;int

a[maxn],c[maxn];

int n;

inline

int lowbit(int

i)void update(int i, intx)}

int query(int x, int

y)

while(y>0

)

return sumy -sumx;

}

因為樹狀陣列是搭建在二進位制的基礎上的,在迭代求和/更新的過程中複雜度為o(logn)的

而初始化樹狀陣列的過程相當於把原陣列中的0更新為a[i],故在輸入資料時呼叫update即可初始化樹狀陣列

----------------------------------分割線qwq-------------------------

而當樹狀陣列需要同時進行單點查詢和一整個區間的進行修改時

我們對原序列的差分初始化樹狀陣列

(差分求sumi相當於求原序列的a[i]值, 而對整個區間進行整體修改對區間內部的差分無影響,僅對端點的差分有影響

因此區間更新只需要update兩個端點值即可)

複雜度均為o(logn)

嘛qwq 還有同時可以高效率進行區間查詢和區間修改的,需要維護兩個樹狀陣列

qwqwq再次再次改天再寫(qwqwq我會說是我還沒搞清楚嘛=-=犯懶了,回頭再看)

資料結構學習筆記(二)陣列與結構

許多程式設計師只把陣列看作 一片連續的記憶體區域 這只是陣列的實現方式,儘管陣列通常被實現為一片連續的記憶體區域,但實現並非陣列的全部。直觀上,陣列由下標 或稱為索引 和值所組成的序對集合,其中對於每個有定義的下標,都存在乙個與其關聯的值。當把陣列作為抽象資料型別時,更加關心的是能夠在陣列上執行的操...

資料結構學習記錄 指標與陣列

陣列一旦被定義,陣列元素將在記憶體中占用一塊連續的儲存單元,陣列名就是這塊連續記憶體單元的首位址。c語言規定 對於指標的算數運算,是以指標指向的資料型別所占用的記憶體單元數為單位1 一維陣列與指標 例如 int a 5 p,q p a 0 陣列a表示陣列元素a 0 的位址,那麼a 1代表元素a 1 ...

資料結構學習

什麼是資料結構 對計算機記憶體中的資料的一種安排。資料結構有那些?優缺點?1.陣列 插入快 知道下標 查詢慢,刪除慢,大小固定 2.有序陣列 比無序的查詢塊,刪除和插入慢,大小固定 3.棧 吃多了吐 個人理解 4.佇列 吃多了拉 個人理解 5.鍊錶 插入快,刪除快,查詢慢 6.二叉樹 查詢 插入 刪...