數論分塊
大部分內容來源於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\) 分的塊一致。