[学习笔记]min_25筛

模板测试链接

传送门

〇、前言

与杜教筛相似的是,\(\tt min\_25\) 筛也是用于计算积性函数的前缀和的,有一些前置芝士与杜教筛相似,如果忘记先去看一看杜教筛吧.

\(\tt min\_25\) 筛主要适用在 \(f(p^k)\) 较好求(\(p\) 为质数),并且对于 \(f\) 可以拆成多个完全积性函数的情况.

壹、推导思路

\(f\) 是一个积性函数,同时定义 \(F(n)=\sum_{i=1}^nf(i)\),我们的目的就是求得 \(F(n)\)\(\tt min\_25\) 筛的主要思路是将前 \(n\) 个数分成 质数、合数、\(1\) 三个部分,我们定义 \(\Bbb P\) 为质数集,\(\Bbb C\) 为合数集,那么

\[F(n)=\sum_{i\in \Bbb P,i\le n}f(i)+\sum_{i\in \Bbb C,i\le n}f(i)+f(1) \]

由于合数最后可以被质数表示,我们先从合数入手……

一、计算合数

合数部分是 \(\sum_{i\in \Bbb C,i\le n}f(i)\).

由于每个合数都可以用质数表示,我们考虑枚举每个合数的最小质因数,将 \(\sum_{i\in \Bbb C,i\le n}f(i)\) 换个写法

\[\begin{aligned}Ans_1&=\sum_{i\in \Bbb C,i\le n}f(i) \\&=\sum_{p\in \Bbb P,p\le n}\sum_{k=1}^{p^k\le n}f(p^k)\left(\sum_{x=1}^{\left\lfloor\frac{n}{p^k}\right\rfloor}f(x)+[k\neq 1]f(1)\right)\end{aligned} \]

同时,我们这里的 \(x\) 要保证其最小质因数必须比 \(p\) 更大.

我们定义 \(S(i,j)\) 表示对于所有 \(1<x\le i\) 的,最小质因数 \(p>j\)\(f(x)\) 之和,我们考虑将 \(S\) 也分成质数、合数进行计算,记 \(G(n)=\sum_{i\in \Bbb P,i\le n}f(i)\),那么我们可以将 \(S(i,j)\) 换一种形式

\[\begin{aligned}S(i,j)=G(i)-G(j)+\sum_{p\in \Bbb P,j<p\le i}\sum_{k=1}^{p^k\le i}f(p^k)\left(\sum_{x=1}^{\left\lfloor\frac{i}{p^k}\right\rfloor}f(x)+[k\neq 1]f(1)\right)\end{aligned} \]

后面那个循环中,必须保证 \(x\) 的最小质因数比 \(p\) 更大.

发现是同样的形式,那么就是

\[S(i,j)=G(i)-G(j)+\sum_{p\in \Bbb P,j<p\le i}\sum_{k=1}^{p^k\le i}f(p^k)\left(S\left(\left\lfloor\frac{i}{p^k}\right\rfloor,p\right)+[k\neq 1]f(1)\right) \]

如果我们知道了 \(G()\),那么我们就可以递归求得 \(S()\) 了.

我们考虑一下 \(S\) 的边界情况,如果 \(i\le j\),那么 \(S(i,j)=0\).

同时,注意到是否有 \(S(n,0)=S(n,1)=F(n)-f(1)\) 这个等式?

那么,我们可以将最后的答案换个写法,有

\[F(n)=S(n,0)+f(1) \]

我们现在唯一需要的,就是如何求 \(G()\) 了.

注意,我们这里的 \(S(i,j)\) 中的 \(j\) 并不是质数下标,而是质数本身,为了防止混乱,所以就这样了.

在这个定义体系下,其实这个 \(j\) 为质数才有意义.

二、如何求 G()

假定我们要求的函数 \(f\) 可以写成 \(f(x)=a_0+a_1x+a_2x^2+...+a_tx^t\),那么我们再定义函数 \(f_i=x^i\),不难发现,对于每一个 \(f_i\) 都是完全积性函数,同时,有 \(f(x)=\sum_{i=0}a_if_i(x)\),所以我们只需要将每个 \(f_i\) 单独算出来,最后带上系数就可以求得最终的 \(f(x)\) 的值.

但是由于我们已知的 \(f(x)\) 是在 \(x\in \Bbb P\) 的情况下的表达式,我们无法算出 \(x\) 不是质数的情况,但是对于我们要求 \(G()\) 而言,是无所谓的,因为我们求的 \(G()\) 只包含质数,对于其他数而言,虽然我们中途可能会计算出一些假的 \(f()\) 的值,但是最后会被同样地筛掉,对于最终结果没有影响.

同时,由于有了这个的影响,我们的 \(S()\) 也只会单个求每个 \(f\) 的值,然后加起来.

考虑怎么求 \(G()\),我们定义

\[g_t(i,j)=\sum_{x\in \Bbb P\; or\; \text{minp}_x>j}^{x\le i}f_t(x)\quad (j\in \Bbb P) \]

其中 \(\text{minp}_x\) 表示 \(x\) 的最小质因数.

接下来我们将下标 \(t\) 省略不写,但是需要明白我们其实一直都只在求原 \(f\) 的一个部分.

对于 \(g\) 的这个定义,我们不难发现 \(G(n)=g(n,\sqrt n)\),或者说 \(G(n)=g(n,x)\),其中 \(x\) 为小于 \(\sqrt n\) 的最大质数.

考虑 \(g(i,j)\) 的转移,设 \(j'\) 为小于 \(j\) 的最大的质数.

\(i<j^2\) 时,质数 \(j\) 筛不去任何质数,这个时候可以直接转移,即

\[g(i,j)=g(i,j') \]

\(i\ge j^2\) 时,从 \(g(i,j')\)\(g(i,j)\),我们筛掉了以 \(j\) 为最小质因数的那些数字,由于 \(f\) 是个完全积性,我们考虑将 \(f(j)\) 这个部分提出来,然后就有

\[g(i,j)=g(i,j')-f(j)\left(g\left(\left\lfloor{i\over j}\right\rfloor,j'\right)-\sum_{k\in \Bbb P}^{k<j}f(k)\right) \]

为什么后面还要减去 \(\sum_{k\in \Bbb P}^{k<j}f(k)\) 这个部分?由于我们的 \(g()\) 包含了上界以内的所有质数,对于需要保证最小质因数为 \(j\) 而言,这一部分是多余的,因而需要去掉.

初始状态有

\[g(i,0)=\sum_{k=2}^if(k) \]

对于 \(k\notin \Bbb P\) 而言,这里的 \(f\) 算出来是假的,但是我们最后使用的都是只含质数的值,对答案没有影响.

注:由于我们的 \(S(i,j)\)\(g(i,j)\) 中的第二维,也就是 \(j\),其实都只会是质数(否则没什么意义),所以我们可以考虑将 \(\sqrt n\) 以内的质数全部处理出来,然后对于 \(j\) 我们不再传质数,而是选择传质数对应在质数表中的下标,这样,原来意义上的 \(j’\) 就是 \(j-1\),因为他们在质数表中的位置仅相差一,同时我们在转移中使用的 \(j\) 就是 \(\text{prime}_j\),并且 \(S(i,0)\neq S(i,1)\),且 \(g(i,0)\neq g(i,1)\).

三、整理

\(S(i,j)\) 表示对于所有 \(1<x\le i\) 的,最小质因数 \(p>\text{prime}_j\)\(f(x)\) 之和.

定义

\[g_t(i,j)=\sum_{x\in \Bbb P\; or\; \text{minp}_x>\text{prime}_j}^{x\le i}f_t(x)\quad (j\in \Bbb P) \]

其中 \(\text{minp}_x\) 表示 \(x\) 的最小质因数.

\(g(i,j)\) 的含义是 \([1,i]\) 中的质数的 \(f(x)\),或者最小质因数大于 \(\text{prime}_j\) 的数的 \(f(x)\) 的值.

\(F(n)=\sum_{i=1}^nf(i)\),并且有

\[F(n)=S(n,0)+f(1) \]

定义 \(P\) 表示小于等于 \(\sqrt n\) 的最大质数.

对于 \(S(i,j)\),我们有

\[S(i,j)= \begin{cases} 0\quad ,i\le \text{prime}_j \\ g(i,P)-g(j,P)+\sum_{p=j+1}^{p\le i}\sum_{k=1}^{\text{prime}_p^k\le i}f(\text{prime}_p^k)\left(S\left(\left\lfloor\frac{i}{\text{prime}_p^k}\right\rfloor,p\right)+[k\neq 1]f(1)\right)\quad ,i>\text{prime}_j \end{cases} \]

其实 \(g(i,P)=G(i)\),只是换了个写法.

对于 \(g(i,j)\),我们有

\[g(i,j)= \begin{cases} \sum_{k=2}^i f(k)\quad ,j=0 \\ g(i,j-1)\quad ,i<\text{prime}_j^2 \\ g(i,j-1)-f(\text{prime}_j)\left(g\left(\left\lfloor{i\over \text{prime}_j}\right\rfloor,j-1\right)-\sum_{k=1}^{k<j}f(\text{prime}_k)\right)\quad ,i\ge \text{prime}_j^2 \end{cases} \]

\(\tt min\_25\) 筛适用的函数 \(f\) 满足以下特性:

  • \(f\) 是积性函数;
  • \(n\le 10^{10}\)
  • \(f(p)\) 是多项式函数(\(p\in \Bbb P\));
  • \(f(p^k)\) 可以较为快速地求出 (\(p\in \Bbb P\));

四、时间复杂度

结论是 \(\mathcal O(\frac{n^{3\over 4}}{\ln n})\),能用就行.

贰、实现细节

由于我们最后只求 \(S(n,0)\),所以我们会调用 \(g(\left\lfloor \frac{n}{i}\right\rfloor,P)\),一共就 \(2\sqrt n\) 个数值,考虑分情况进行 \(\tt hash\),即如果 \(\left\lfloor \frac{n}{i}\right\rfloor\le \sqrt n\),那么将编号存到 \(\tt id1[\left\lfloor \frac{n}{i}\right\rfloor]\) 中,如果 \(\left\lfloor \frac{n}{i}\right\rfloor>\sqrt n\),那么将编号存到 \(\tt id2[\left\lfloor \frac{n}{\frac{n}{i}}\right\rfloor]\) 中,总而言之,我们要让下标在 \(\sqrt n\) 的范围之内,这样才能用更小的空间存下标号.

并且,由于 \(g(i,j)\)\(j\) 一直都是 \(P\),所以代码实现时只需要一维就可以了.

而这一维我们将其离散了,放在 \(\tt id1,id2\) 里面.

叁、例题

模板

[LOJ6053]简单的函数

posted @ 2021-02-01 16:38  Arextre  阅读(115)  评论(0编辑  收藏  举报