数论分块学习笔记

数论分块学习笔记

性质

数论分块用于快速计算含有除法向下取整的和式,即形如 \(\sum_{i=1}^nf(i)g(\lfloor\frac{n}{i}\rfloor)\) 的式子。当预处理出 \(f\) 的前缀和时,数论分块可以在 \(O(\sqrt{n})\) 的时间复杂度下计算上述和式的值。

求解

引理 \(1\)

\(\forall a,b,c\in\mathbb{z},\lfloor\frac{a}{bc}\rfloor=\lfloor\frac{\lfloor\frac{a}{b}\rfloor}{c}\rfloor\)

证明:

不妨设 \(a=kb+r(0\le r<b)\),那么 \(\lfloor\frac{a}{b}\rfloor=k\)

所以有 \(\lfloor\frac{a}{bc}\rfloor=\lfloor\frac{\frac{a}{b}}{c}\rfloor=\lfloor\frac{k+\frac{r}{b}}{c}\rfloor\)

因为 \(k\) 是整数,\(r<b\),所以 \(\lfloor\frac{k+\frac{r}{b}}{c}\rfloor=\lfloor\frac{k}{c}\rfloor=\lfloor\frac{\lfloor\frac{a}{b}\rfloor}{c}\rfloor\)

\(\lfloor\frac{a}{bc}\rfloor=\lfloor\frac{\lfloor\frac{a}{b}\rfloor}{c}\rfloor\)

引理 \(2\)

\(\forall n\in\mathbb{N}_+,|\{\lfloor\frac{n}{d}\rfloor|d\in\mathbb{N}_+,d\le n\}|\le \lfloor2\sqrt{n}\rfloor\)​。

证明:

对于 \(d\le\lfloor\sqrt{n}\rfloor\),有 \(\lfloor\frac{n}{d}\rfloor\) 最多有 \(\lfloor\sqrt{n}\rfloor\) 种取值,因为 \(d\) 最多有 \(\lfloor\sqrt{n}\rfloor\) 种取值。

对于 \(d>\lfloor\sqrt{n}\rfloor\),有 \(\lfloor\frac{n}{d}\rfloor\) 最多有 \(\lfloor\sqrt{n}\rfloor\) 种取值,因为 \(\lfloor\frac{n}{d}\rfloor\le\lfloor\sqrt{n}\rfloor\)

\(\forall n\in\mathbb{N}_+,|\{\lfloor\frac{n}{d}\rfloor|d\in\mathbb{N}_+,d\le n\}|\le \lfloor2\sqrt{n}\rfloor\)

结论:

对于两个整数 \(n,i\),满足 \(\lfloor\frac{n}{i}\rfloor=\lfloor\frac{n}{j}\rfloor,i\le j\le n\) 的最大的 \(j\) 值为 \(\lfloor\frac{n}{\lfloor\frac{n}{i}\rfloor}\rfloor\)

证明:

即若存在 \(i\) 使得 \(\lfloor\frac{n}{i}\rfloor=k\),则满足 \(\lfloor\frac{n}{j}\rfloor=k\) 的最大的 \(j=\lfloor\frac{n}{\lfloor\frac{n}{i}\rfloor}\rfloor\)

\(j>\frac{n}{k}\),则 \(\lfloor\frac{n}{j}\rfloor<\lfloor\frac{n}{\frac{n}{k}}\rfloor=\lfloor k\rfloor=k\),所以 \(j\le\frac{n}{k}\),即 \(j\le\lfloor\frac{n}{k}\rfloor\)。有 \(\lfloor\frac{n}{j}\rfloor\ge \lfloor\frac{n}{\frac{n}{k}}\rfloor=\lfloor k\rfloor=k\),若不能取等,则说明没有 \(j\) 使得 \(\lfloor\frac{n}{j}\rfloor=k\),这与存在 \(i\) 使得 \(\lfloor\frac{n}{i}\rfloor=k\) 矛盾,故能够取等,又因为 \(\lfloor\frac{n}{j}\rfloor\)\(j\) 减少而单调不减,所以当 \(j=\lfloor\frac{n}{k}\rfloor\)\(\lfloor\frac{n}{j}\rfloor=k\),所以 \(j\) 的最大值为 \(\lfloor\frac{n}{k}\rfloor=\lfloor\frac{n}{\lfloor\frac{n}{i}\rfloor}\rfloor\)

如此可以得到以下几个性质:

  • \(\lfloor\frac{n}{i}\rfloor\) 的值的个数不超过 \(\lfloor2\sqrt{n}\rfloor\),也就是说,枚举 \(\lfloor\frac{n}{i}\rfloor\) 的时间复杂度是 \(O(\sqrt{n})\)
  • 通过 \(\lfloor\frac{n}{i}\rfloor\),假设使得这个值不变的区间的范围是 \([l,r]\),那么可以在 \(O(1)\) 时间内求解出该区间的最右边,并且 \(r+1\) 一定是下一个区间的最左边。

那么就有以下的代码思路:

考虑当 \(\lfloor\frac{n}{i}\rfloor\) 的值不变时,对于这些项的求和 \(\sum_{i=l}^rf(i)g(\lfloor\frac{n}{i}\rfloor)=g(\lfloor\frac{n}{i}\rfloor)\sum_{i=l}^rf(i)\),显然后半部分可以利用前缀和求出,只需要求出前半部分的值即可。

\(l=1\) 开始枚举,每次考虑区间 \([l,\lfloor\frac{n}{\lfloor\frac{n}{l}\rfloor}\rfloor]\) 对答案的贡献,也就是 \(g(\lfloor\frac{n}{l}\rfloor)\sum_{i=l}^{\lfloor\frac{n}{\lfloor\frac{n}{l}\rfloor}\rfloor}f(i)\)。后半部分利用前缀和快速求解,前半部分直接计算即可。

最后令 \(l=\lfloor\frac{n}{\lfloor\frac{n}{l}\rfloor}\rfloor+1\),作为下一个枚举区间的左端点。

显然这样的复杂度是 \(O(\sqrt{n})\) 的。

代码

for(int l=1,r;l<=n;l=r+1){
	r=n/(n/l);
    ans+=(f[r]-f[l-1])*g[n/l];
}

一般化

特别的,如果在和式中出现了 \(\lfloor\frac{a_1}{i}\rfloor,\lfloor\frac{a_2}{i}\rfloor,\cdots,\lfloor\frac{a_n}{i}\rfloor\) 的多个整除式,需要在每一个区间的右端点中取最小值。

拓展

对于上取整的形式也同时拥有这些性质,但更多的是倒序来讲,也就是对于两个整数 \(n,i\),满足 \(\lfloor\frac{n}{i}\rfloor=\lfloor\frac{n}{j}\rfloor,1\le j\le i\) 的最小的 \(j\) 值为 \(\lfloor\frac{n}{\lfloor\frac{n}{i}\rfloor}\rfloor\)。那么我们可以修改枚举顺序,即先让 \(r\) 取到最大值,接着让 \(l\) 取到对应左端点后,下一次令 \(r=l-1\) 即可,一般化也同样适用。

posted @ 2024-04-02 21:15  DycIsMyName  阅读(12)  评论(0编辑  收藏  举报