演算法學習筆記(21):數論分塊

Qerrj發表於2024-06-06

數論分塊

大部分內容來源於OI-WIKI

引理1: \(\\forall a,b,c\in\mathbb{Z},\left\lfloor\frac{a}{bc}\right\rfloor=\left\lfloor\frac{\left\lfloor\frac{a}{b}\right\rfloor}{c}\right\rfloor\)

引理2: \(\lfloor \frac{n}{i} \rfloor\) 的取值有 \(O(\sqrt n)\)

引理 1 可以把一些分母搬上去, 轉化成引理 2 的形式。 考慮引理 2 的式子的性質, 這啟發我們計算 \(\sum \frac{n}{i}\)
可以快速統計。

有一個結論: 取值為 \(\large\frac{n}{l}\) 的最大的 \(i\) 等於 \(\large\lfloor \frac{n}{\lfloor\frac{n}{l}\rfloor} \rfloor\)

所以我們就可以這麼算 \(\large\sum \frac{n}{i}\)

int Sum(int x) {
	int l = 1, r = 0, res = 0;
	while(l <= x) {
		r = x / (x / l);
		res += (r - l + 1) * (x / l);
		l = r + 1;
	}
	return res;
}

擴充的, 當我們需要計算 \(\large\sum f_i \times \frac{n}{i}\)時:

可以把 res += (r - l + 1) * (x / l); 替換成 res += (f[r] - f[l - 1]) * (x / l);

再擴充地: 取值為 \(\large\frac{n}{l}\) 的最大的 \(i\)\(\large\lfloor \frac{n - 1}{\lfloor\frac{n - 1}{l}\rfloor} \rfloor\)

不嚴謹的證明:

引理4: \(\left\lceil\dfrac ni\right\rceil=\left\lfloor\dfrac{n-1}i\right\rfloor+1\)

證明: \(\left\lfloor\dfrac{n-1}i\right\rfloor+1 = \left\lfloor\dfrac{n-1 + i}i\right\rfloor\), 考慮 $\dfrac{i - 1}{i} < 1 $, 所以易得前面的式子成立。

所以 \(\large\left\lceil\dfrac ni\right\rceil\) 分的塊和 \(\left\lfloor\dfrac{n-1}i\right\rfloor\) 分的塊一致。

相關文章