Min_25筛详解

概述

Min_25是日本一个ACM选手的ID,这个筛法是他发明的,所以称之为Min_25筛。它能在亚线性复杂度求出一类积性函数的 f f f 的前缀和,前提 是这个积性函数在质数和质数的幂位置的函数值比较好求。借助埃拉托色尼筛的思想 将原问题转化成与质因子相似的子问题,从而得到一个递推式,达到快速求解的效果。

对比其他算法

在这里插入图片描述

(绿色为 O ( n ) O(n) O(n),红色为Min_25筛,蓝色为杜教筛)
可以发现,Min_25时间复杂度尽管只快了杜教筛常数级,但终究是快的

因为Min_25筛不像杜教筛那样需要构造,所以Min_25筛的适用范围更加的广泛。

算法原理

为了方便描述,我们定义一些符号。

  • 设我们的问题是 F ( n ) = ∑ i = 1 n f ( i ) F(n)=\sum\limits_{i=1}^{n}f(i) F(n)=i=1nf(i) ;假定 f f f 是一个完全积性函数。

  • m i n p ( i ) minp(i) minp(i) 表示 i i i 的最小质因子。

  • p r k pr_k prk 表示第 k k k 个质数。

  • ∣ p r ( n ) ∣ |pr(n)| pr(n) 表示 n n n 以内的质数个数。

  • g ( n , i ) g(n,i) g(n,i) 表示在埃拉托色尼筛中,前 i i i 个筛完后,剩下的数的 f f f 值之和。即质数和最小质因子大于 p r i pr_i pri 的合数。

则有
g ( n , i ) = ∑ ( j ∈ P r i m e ) ∨ ( m i n p ( j ) > p r i ) f ( j ) g(n,i)=\sum\limits_{(j\in Prime)\lor(minp(j)>pr_i)}f(j) g(n,i)=(jPrime)(minp(j)>pri)f(j)
于是可知 g ( n , ∣ p r ( n ) ∣ ) g(n,|pr(n)|) g(n,pr(n)) 表示的是做完埃氏筛之后, n n n 以内所有质数 f f f 值之和, g ( p r k , k ) g(pr_k,k) g(prk,k) 表示的是 前 k k k 个质数的 f f f 值之和(含义差不多)

发现可以用如下的递推式求出 g ( n , i ) g(n,i) g(n,i) 的值。
g ( n , i ) = { g ( n , i − 1 ) , p r i 2 > n g ( n , i − 1 ) − f ( p r i ) × ( g ( ⌊ n p r i ⌋ , i − 1 ) − g ( p r i − 1 , i − 1 ) ) p r i 2 ≤ n g(n,i)=\begin{cases}g(n,i-1),& pr_i^2> n\\g(n,i-1)-f(pr_i)\times(g(\lfloor\dfrac{n}{pr_i}\rfloor,i-1)-g(pr_{i-1},i-1))&pr_i^2\le n\end{cases} g(n,i)= g(n,i1),g(n,i1)f(pri)×(g(⌊prin,i1)g(pri1,i1))pri2>npri2n

第一行的式子很容易理解,回忆埃氏筛的方法, n n n 第一次一定是被最小质因子筛掉。 p r i 2 > n pr_i^2>n pri2>n,那么 p r i pr_i pri 不会筛掉任何数,便不会产生任何贡献。

但是第二个式子就比较难理解了,我也花了十几分钟的时间才彻底明白。
首先, g ( n , i ) g(n,i) g(n,i) g ( n , i − 1 ) g(n,i-1) g(n,i1) 而言,就是以 p r i pr_i pri 为最小质因子的数被筛掉了,那么减去的就应该是 n n n 以内以 p r i pr_i pri 为最小质因子的数。

g ( ⌊ n p r i ⌋ , i − 1 ) g(\lfloor\dfrac{n}{pr_i}\rfloor,i-1) g(⌊prin,i1) ,除去了一个 p r i pr_i pri ,得到的 ⌊ n p r i ⌋ \lfloor\dfrac{n}{pr_i}\rfloor prin n n n 以内以 p r i pr_i pri 为质因子能筛掉的数中,可能出现的除 p r i pr_i pri 以外倍数的最大值。
所以 g ( ⌊ n p r i ⌋ , i − 1 ) g(\lfloor\dfrac{n}{pr_i}\rfloor,i-1) g(⌊prin,i1) 得到的是 ⌊ n p r i ⌋ \lfloor\dfrac{n}{pr_i}\rfloor prin 以内 m i n p ( x ) ≥ p r i − 1 minp(x)\ge pr_{i-1} minp(x)pri1 f f f 值和 ∑ j ∈ P r i m e p r i − 1 f ( j ) \sum\limits_{j\in Prime}^{pr_{i-1}}f(j) jPrimepri1f(j) 之和。

但是埃氏筛时只有满足 m i n p ( x ) ≥ p r i − 1 minp(x)\ge pr_{i-1} minp(x)pri1 的才会被筛掉啊,所以得把 ∑ j ∈ P r i m e p r i − 1 f ( j ) \sum\limits_{j\in Prime}^{pr_{i-1}}f(j) jPrimepri1f(j) 给加回来, ∑ j ∈ P r i m e p r i − 1 f ( j ) \sum\limits_{j\in Prime}^{pr_{i-1}}f(j) jPrimepri1f(j) 即为 g ( p r i − 1 , i − 1 ) g(pr_{i-1},i-1) g(pri1,i1)

这样它们再乘一个 p r i pr_i pri ,则得到 n n n 以内的最小质因子等于 p r i pr_i pri 的合数的 f f f 值。注意这里,要求 f f f 是一个完全积性函数,才能把 f ( p r i ) f(pr_i) f(pri) 提取出来。但是 f f f 不一定是一个积性函数啊?带着疑问继续往下看。


注意这个递推式,它的初始条件是什么呢?是 g [ n ] [ 0 ] g[n][0] g[n][0] ,而 g [ n ] [ 0 ] g[n][0] g[n][0] 的意义正是还没有开始进行埃氏筛时的 f f f 值之和。这个值是我们需要去求的,怎么可能拿来做初始值呢?

其实这里的 g [ n ] [ 0 ] g[n][0] g[n][0] 里,并不是真正的 f f f 值之和,假设它为 f ′ f' f 。在质数和质数的幂的位置, f ′ = f f'=f f=f;而其他位置不一定, f ′ f' f 出现的目的,只是因为这里需要一个完全积性函数,而原来的 f f f 虽然是一个积性函数,但不是完全积性函数。于是用 f ′ f' f 去代替 f f f。这样,前面的递推式就成立了。

有时候题目中的 f f f多项式,我们可以将它拆开,这样每一项都是一个幂的形式,而幂是完全积性函数。这样对每一项通过 g g g 的递推式去求,求出后再求和即可。


怎么实现呢?

注意到第二维是可以滚动的,所以空间上可以省掉第二维;有因为 ⌊ ⌊ n a ⌋ b ⌋ = ⌊ n a b ⌋ \left\lfloor\dfrac{\lfloor\frac{n}{a}\rfloor}{b}\right\rfloor=\lfloor\dfrac{n}{ab}\rfloor ban=abn,这说明递归下去求的所有 g g g 值,都在数论分块的 2 n 2\sqrt{n} 2n 个值中。所以我们一开始就把 2 n 2\sqrt{n} 2n 个值先存下来,然后在上面进行滚动。


现在进入正题,上面的都是预处理。

S ( n , i ) S(n,i) S(n,i) 表示 n n n 以内的最小质因子大于 p r i pr_i pri 的数的 f f f 值之和。
则有 S ( n , i ) = g ( n , ∣ P ∣ ) − g ( p r i , ∣ P ∣ ) + ∑ j > i ∑ p r j k ≤ n f ( p r j k ) × ( S ( ⌊ n p r j k ⌋ , j + [ k > 1 ] ) S(n,i)=g(n,|P|)-g(pr_i,|P|)+\sum\limits_{j>i}\sum\limits_{pr_j^k\le n}f(pr_j^k)\times(S(\lfloor\frac{n}{pr_j^k}\rfloor,j+[k>1]) S(n,i)=g(n,P)g(pri,P)+j>iprjknf(prjk)×(S(⌊prjkn,j+[k>1])

这里有同学提出过问题,为什么不能把 g ( n , ∣ P ∣ ) − g ( p r i , ∣ P ∣ ) g(n,|P|)-g(pr_i,|P|) g(n,P)g(pri,P) 去掉,将 [ k > 1 ] [k>1] [k>1] 改成 [ k ≥ 1 ] [k\ge1] [k1] 呢?
可以是可以的,但是就必须要把 n n n 以内所有的质数都枚举出来
那 O(n) 的时间复杂度和直接暴力求前缀和有什么区别?

我们最终要求的值为 S ( n , 0 ) + f ( 1 ) S(n,0) + f(1) S(n,0)+f(1)。(加上 f ( 1 ) f(1) f(1) 是因为1没有质因子,不会被 S ( n , 0 ) S(n,0) S(n,0) 所包括)。

观察上述的递推式,其中的两项已经求出来了,最后的那一项有两个求和号,分别枚举质因子以及质因子的次数,注意此处根据“递归下去求的所有 g g g 值,都在数论分块的 2 n 2\sqrt{n} 2n 个值中”,要求的质因子为 n \sqrt n n 以内的质因子,所以枚举的总次数大约是: n ln ⁡ n × ln ⁡ n \sqrt{\dfrac{n}{\ln n}}\times\ln n lnnn ×lnn,而 S ( ⌊ n p r j k ⌋ ) S(\lfloor\dfrac{n}{pr_j^k}\rfloor) S(⌊prjkn⌋)中的参数,也是在 n n n 的数论分块的 O ( n ) O(\sqrt n) O(n ) 个值以内。

分析时间复杂度

T ( n ) T(n) T(n) 表示上述递推式的时间复杂度,则有:
T ( n ) = O ( n ln ⁡ n × ln ⁡ n ) + ∑ p r j k T ( ⌊ n p r j k ⌋ ) T(n)=O(\sqrt{\dfrac{n}{\ln n}}\times\ln n)+\sum\limits_{pr_j^k}T(\lfloor\dfrac{n}{pr_j^k}\rfloor) T(n)=O(lnnn ×lnn)+prjkT(⌊prjkn⌋)

= O ( n ln ⁡ n × ln ⁡ n ) + 1 ln ⁡ n ∑ i = 2 n T ( ⌊ n i ⌋ ) =O(\sqrt{\dfrac{n}{\ln n}}\times\ln n)+\dfrac{1}{\ln n}\sum\limits_{i=2}^{n}T(\lfloor\dfrac{n}{i}\rfloor) =O(lnnn ×lnn)+lnn1i=2nT(⌊in⌋)

= O ( n ln ⁡ n × ln ⁡ n ) + 1 ln ⁡ n ∑ i = 2 n O ( n i ln ⁡ ( n i ) × ln ⁡ ( n i ) ) =O(\sqrt{\dfrac{n}{\ln n}}\times\ln n)+\dfrac{1}{\ln n}\sum\limits_{i=2}^{n}O(\sqrt\dfrac{\frac{n}{i}}{\ln(\frac{n}{i})}\times\ln(\frac{n}{i})) =O(lnnn ×lnn)+lnn1i=2nO(ln(in)in ×ln(in))

= O ( n ln ⁡ n × ln ⁡ n ) + 1 ln ⁡ n ∑ i = 2 n O ( i ln ⁡ ( i ) × ln ⁡ ( i ) + n i ln ⁡ ( n i ) × ln ⁡ ( n i ) =O(\sqrt{\dfrac{n}{\ln n}}\times\ln n)+\dfrac{1}{\ln n}\sum\limits_{i=2}^{\sqrt n}O(\sqrt\dfrac{i}{\ln(i)}\times\ln(i)+\sqrt\dfrac{\frac{n}{i}}{\ln(\frac{n}{i})}\times\ln(\frac{n}{i}) =O(lnnn ×lnn)+lnn1i=2n O(ln(i)i ×ln(i)+ln(in)in ×ln(in)

≥ O ( n ln ⁡ n × ln ⁡ n ) + 1 ln ⁡ n ∑ i = 2 n O ( n ln ⁡ n 4 ) \ge O(\sqrt{\dfrac{n}{\ln n}}\times\ln n)+\dfrac{1}{\ln n}\sum\limits_{i=2}^{\sqrt n}O(\sqrt[4]{n\ln \sqrt n}) O(lnnn ×lnn)+lnn1i=2n O(4nlnn )

= O ( n ln ⁡ n × ln ⁡ n ) + O ( n 3 4 ln ⁡ n × ln ⁡ n 4 ) =O(\sqrt{\dfrac{n}{\ln n}}\times\ln n)+O(\dfrac{n^{\frac{3}{4}}}{\ln n}\times\sqrt[4]{\ln \sqrt{n}}) =O(lnnn ×lnn)+O(lnnn43×4lnn )

= O ( n 3 4 ln ⁡ n ) =O(\dfrac{n^\frac{3}{4}}{\ln n}) =O(lnnn43)

例题

【模板】Min_25筛

简单的函数

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值