莫比烏斯反演(一)
前言
終於要學莫比烏斯反演啦,封存了半年數論,爲了一個星期後的南昌,不得不擴充更廣的知識面。遺憾的是,打完南昌可能就要退役了。
雖然打完南昌一站可能退役了,但是也不能放棄算法的學習。
(2019-05-26 留)
整除分塊
在莫比烏斯反演一類問題中,結果經常會出現形如 ∑i=1n⌊in⌋。
如果 n 的範圍巨大,暴力 O(n) 的方法可能會超時。而整除分塊是 O(n) 的方法。
現在我們要解決一個這樣的問題:
i=1∑n⌊in⌋(n≤1012)
解釋
參考博客:點擊此鏈接看證明
首先我們可以想到的是 ∑i=1n⌊in⌋ 裏面,有很多項是重複的。例如在 n=10 的情況下,1 至 10 項分別是 10,5,3,2,2,1,1,1,1,1 。而整除分塊的任務就是 ∑i=110⌊i10⌋=10×1+5×1+3×1+2×2+1×5。
∑i=1n⌊in⌋ 的性質:
- 不同的項最多隻有 2n 項。
- 與 ⌊in⌋ 相等的最大的 i′ 爲 ⌊⌊in⌋n⌋。
代碼
for (int l = 1, r; l <= n; l = r + 1) {
r = n / (n / l);
ans += (r - l + 1) * (n / l);
}