分塊
數列上的分塊
複習一下
當我們想要做RMQ(區間極值)時
我們會使用sparse table, 線段樹...
但其實有另一個做法,稱作分塊
分塊
7 | 1 | 2 | 4 | 6 | 3 | 8 | 9 | 5 |
---|
7 | 6 | 9 |
---|
每\(K\)格記錄答案
詢問
7 | 1 | 2 | 4 | 6 | 3 | 8 | 9 | 5 |
---|
7 | 6 | 9 |
---|
若有覆蓋到整塊->直接查
沒被蓋到的最多\(2K\)->暴力做
修改
7 | 1 | 2 | 4 | 0 | 3 | 8 | 9 | 5 |
---|
7 | 4 | 9 |
---|
只會影響到那塊
就暴力跑完,維護好答案
複雜度
詢問: \(O(N/K+K)\)
修改: \(O(K)\)
根據算幾不等式,\(K+(N/K)\geq 2\sqrt{K\times (N/K)}\)
等號成立條件: \(K=N/K\)
所以當\(K=\sqrt N\)時,複雜度最好
等等...
以前提到的BIT、線段樹複雜度都是\(O(logN)\)
比分塊更好,那分塊有什麼用?
- (可能)比較好寫
- 處理一些資料結構做不到或不好做的事
例題
中國人插隊問題
有 \(N\) 筆操作
\(1 x id\): 編號為 \(id\) 的人插隊到第 \(x\) 個位置
\(2 x\): 排在第 \(x\) 個位置的人走了
\(3 x\): 詢問排在第 \(x\) 個位置的人的編號
不那麼直覺的分塊
Counting Triangles
給定一張圖,\(N\)個點\(M\)條邊
對於三個點 a, b, c (a<b<c),若a,b和b,c和c,a之間都有邊
則 a, b, c 形成一個三角形。
請問整張圖總共有多少三角形?
\(N, M\leq 10^5\)
Counting Triangles
假設我們可以\(O(1)\)回答\((x,y)\)之間是否有一條邊
那麼對於圖上任意一點 \(v\),可以
- \(O(M)\) 時間算出有多少個包含點 \(v\) 的三角形
- \(O(d^2)\) 時間算出有多少個包含點 \(v\) 的三角形 (\(d\) 為 \(v\) 的點度)
Counting Triangles
對於點度 \(< K\) 的點,我們花 \(O(\sum d_i^2)\) 時間做
\(O(\sum d_i^2)=O(K\times \sum d_i)=O(K\times M)\)
剩下的點花 \(O(M\times C)\) 的時間做
定義 \(C\) 為點度 \(\geq K\) 的點數數量
可以得知,\(C\leq 2M/K\)
總複雜度: \(O(K\times M+M^2/K)\)
取 \(K=\sqrt M\) 時有最好複雜度 \(O(M\sqrt M)\)
Codeforces 1207F
給一個長度為 \(5\times 10^5\) 的序列(初始為全零),有 \(Q\) 筆操作
\(1 x y\) : 將第 \(x\) 個數字加上 \(y\)
\(2 x y\) : 求序列中所有編號除以 \(x\) 餘 \(y\) 的數字和
\(Q \leq 5\times 10^5\)
TIOJ 1674
給定數字 \(N\),求 \(\sum_{i=1}^{N} N mod i\)
\(N\leq 10^{13}\)
2020 NPSC 初賽 pA
有 \(N\) 個人,每 \(x\) 個人一組,從 \(1\) 號開始依序分。定義 \(f(i)\) 為考慮 \(x=1, x=2, ... , x=N\) 這 \(N\) 種情況時,編號 \(i\) 的人分不到組的狀況總數
給定 \(L, R\),求\(f(L), f(L+1), ... ,f(R)\)
\(1\leq N\leq 2^{40}\),\(R-L\leq 3\times 10^5\)
分塊
By jass921026
分塊
- 793