序:
关于这个筛法,此前是在学习了杜教筛的基础上的,杜教筛有良好的复杂度 O ( n 2 3 ) O(n^\frac{2}{3}) O(n32),而且实现简单。唯一的不足之处就是函数本身需要满足一些特殊的条件(即我们需要找另一个积性函数,使其与所求函数的狄利克雷卷积是一个很容易求前缀的式子),而且与函数本身的积性性质没有太大关系。后来接触到洲阁筛,这种筛法是一种解决更加广泛的积性函数前缀和,但是实在不太好写(因为我太菜了),后来在秦皇岛,复旦的温老师介绍了一个新的筛法,不过后来老师没怎么讲这个,因为时间不够了,然后就很匆忙提了一下。对于这么偏的东西,我还是去刷其他的题去了。。。后来一次偶然的机会,我遇到了一个类似的需要用这种方法的题目,后来就决定自己学EES,网上一查,发现根本就没有这样的东西。。。后来按照课件,我大概是明白了一点,但是还有后半部的问题,我始终没有解决,而且这个东西我周围没一个人会,网上也查不到。。。于是这篇写了一半草稿在18年9月就一直封存着了,后来就慢慢忘了。。。直到前几天,偶然的机会,又谈到这个问题,终于搞明白了。
提出问题:
f
(
x
)
是
一
个
积
性
函
数
,
且
当
x
=
p
k
时
(
p
为
质
数
)
,
f
(
x
)
是
一
个
关
于
p
的
多
项
式
f(x)是一个积性函数,且当x=p^k时(p为质数),f(x)是一个关于p的多项式
f(x)是一个积性函数,且当x=pk时(p为质数),f(x)是一个关于p的多项式
求
S
(
n
)
=
∑
i
=
1
n
f
(
i
)
,
n
<
=
1
0
12
S(n)=\sum_{i=1}^nf(i),n<=10^{12}
S(n)=i=1∑nf(i),n<=1012
问题的一般化描述便是如此。显然问题的难点是在n的数量级上。这种筛法便是解决相关问题,如果n小于
1
0
8
10^{8}
108,我们可以用欧拉线性筛在
O
(
n
)
O(n)
O(n)的时间复杂度解决这个问题。
分析:
设自然数集合
N
=
{
x
∣
2
<
=
x
<
=
n
}
N=\{ x|2<=x<=n\}
N={x∣2<=x<=n},我们按照一种划分标准,将这个集合里的数分成两部分。
这个标准是,先把一个数
x
x
x唯一分解:
x
=
∏
i
=
1
k
p
i
a
i
,
p
i
为
质
数
,
p
i
<
p
i
+
1
,
a
i
>
=
1
x=\prod_{i=1}^k p_i^{a_i},p_i为质数,p_i<p_{i+1},a_i>=1
x=i=1∏kpiai,pi为质数,pi<pi+1,ai>=1
划分标准为:我们取这个数的最大质因子
p
k
p_k
pk,若这个质因子的次数即
a
k
=
1
a_k=1
ak=1,即x属于集合
N
1
N_1
N1,反之,x属于
N
2
N_2
N2,即
a
k
>
1
a_k>1
ak>1
显然
N
1
∩
N
2
=
∅
,
N
1
∪
N
2
=
N
N_1\cap N_2=\emptyset,N_1\cup N_2=N
N1∩N2=∅,N1∪N2=N
对 N 1 , N 2 N_1,N_2 N1,N2中的数,我们来讨论一下他们的性质,很容易证明有: ∀ x ∈ N 1 , 则 ( 若 存 在 ) 其 次 大 质 因 子 p k − 1 < n \forall x \in N_1,则(若存在)其次大质因子p_{k-1}<\sqrt n ∀x∈N1,则(若存在)其次大质因子pk−1<n
∀
x
∈
N
2
,
则
其
最
大
质
因
子
p
k
<
=
n
\forall x \in N_2,则其最大质因子p_{k}<=\sqrt n
∀x∈N2,则其最大质因子pk<=n
解决问题的第一步:
现在我们枚举一类数 x x x,我们记 P x P^x Px是 x x x的质因子的集合,
我们枚举集合 N N N中的数x,满足: ∀ p ∈ P x , p < = n \forall p\in P^x,p<=\sqrt n ∀p∈Px,p<=n
满则条件的x构成一个集合,记为 N 1 2 N^{\frac{1}{2}} N21,
那么实现的时候,我们可以DFS n \sqrt n n以内的质因子.当 n < 1 0 13 n<10^{13} n<1013时, ∣ N 1 2 ∣ ≈ n 3 4 l o g n |N^{\frac{1}{2}}|\approx \frac{n^{\frac{3}{4}}}{logn} ∣N21∣≈lognn43,这里的证明比较复杂,暂不讨论。
接下来,我们记 L x 为 x L_x为x Lx为x的最大质因子。
对于答案来说这个集合里的还少了质因子是大于 n \sqrt n n的数
现在我们枚举来集合
N
1
2
N^{\frac{1}{2}}
N21,
∀
x
∈
N
1
2
如
果
x
∈
N
1
,
则
S
(
n
)
+
=
f
(
x
)
∗
∑
L
x
<
i
<
=
n
x
[
i
是
质
数
]
∗
f
(
i
)
反
之
,
S
(
n
)
+
=
f
(
x
)
\forall x \in N^{\frac{1}{2}}\\ 如果\ x\in N_1,则S(n)+=f(x)*\sum_{L_x<i<=\frac{n}{x}}[i是质数]*f(i)\\反之,S(n)+=f(x)
∀x∈N21如果 x∈N1,则S(n)+=f(x)∗Lx<i<=xn∑[i是质数]∗f(i)反之,S(n)+=f(x)
显然,这里是利用了函数的积性来求得那些质因子是大于
n
\sqrt n
n的数对于答案的贡献。
在实现的时候,显然当
L
x
>
=
n
x
L_x>=\frac{n}{x}
Lx>=xn,可以及时退出,不然对效率还是有影响的。
问题转化为一个子问题:
那么现在的问题就只剩下求
∑
L
x
<
i
<
=
n
x
[
i
是
质
数
]
∗
f
(
i
)
\sum_{L_x<i<=\frac{n}{x}}[i是质数]*f(i)
Lx<i<=xn∑[i是质数]∗f(i),
我们记:
g
(
n
)
=
∑
i
=
1
n
[
i
是
质
数
]
∗
f
(
i
)
g(n)=\sum_{i=1}^n[i是质数]*f(i)
g(n)=i=1∑n[i是质数]∗f(i),
则求的是
g
(
⌊
n
x
⌋
)
−
g
(
L
x
)
g(\lfloor\frac{n}{x}\rfloor)-g(L_x)
g(⌊xn⌋)−g(Lx)
因为 L x L_x Lx是小于 n \sqrt n n,所以这里欧拉筛也可以处理,反正这个很容易处理。
现在问题的真正关键是求 g ( ⌊ n x ⌋ ) ( 或 g ( n ) ) g(\lfloor\frac{n}{x}\rfloor)(或g(n)) g(⌊xn⌋)(或g(n)),
回过头观察 f ( x ) f(x) f(x), f ( x ) f(x) f(x)是只有在x为质数是才有多项式,我们不妨设一个函数 f ′ ( x ) f'(x) f′(x),他对于全体整数都满足这个多项式,那么我们发现: g ( n ) = ∑ i = 1 n [ i 是 质 数 ] ∗ f ( i ) = ∑ i = 1 n [ i 是 质 数 ] ∗ f ′ ( i ) g(n)=\sum_{i=1}^n[i是质数]*f(i)=\sum_{i=1}^n[i是质数]*f'(i) g(n)=i=1∑n[i是质数]∗f(i)=i=1∑n[i是质数]∗f′(i),
而多向式的求和,是很容易的!我们只要把不符合条件的筛掉就可以,并且显然 f ′ ( x ) f'(x) f′(x)是完全积性函数,即 f ′ ( a b ) = f ′ ( a ) f ′ ( b ) f'(ab)=f'(a)f'(b) f′(ab)=f′(a)f′(b)
假设这个多项式有k次: ∑ i k a i p i \sum_i^{k}a_ip^i ∑ikaipi,那么实际上我们只要执行下面的算法k+1次, a i a_i ai这个系数在执行完以后在乘上就行,所以我们只要先讨论: f ′ ( p ) = p k f'(p)=p^k f′(p)=pk,这个东西求和不难,组合数学的东西
解决子问题:
我们可以回想一下
E
r
a
t
o
s
t
h
e
n
e
s
S
i
e
v
e
Eratosthenes\ Sieve
Eratosthenes Sieve的筛法是怎么样的。从小到大,枚举质数把后面的是这个是质数倍数的数去除。实际上这个也是这样的:
从
小
到
大
枚
举
p
∈
P
,
且
p
<
=
n
从小到大枚举p \in P,且p<=\sqrt n
从小到大枚举p∈P,且p<=n
给定
p
p
p以后,我们枚举i:
从
大
到
小
枚
举
i
∈
N
,
当
i
<
p
2
停
止
枚
举
从大到小枚举i\in N,当i<p^2停止枚举
从大到小枚举i∈N,当i<p2停止枚举
利用
f
′
(
x
)
f'(x)
f′(x)的完全积性,执行下面的操作:
g
[
i
]
−
=
(
g
[
⌊
i
p
⌋
]
−
g
[
p
−
1
]
)
∗
f
′
(
p
)
g[i]-=(g[\lfloor\frac{i}{p}\rfloor]-g[p-1])*f'(p)
g[i]−=(g[⌊pi⌋]−g[p−1])∗f′(p)
解释一下:
g
[
i
]
g[i]
g[i]和
g
(
i
)
g(i)
g(i)含义略有不同,
g
[
i
]
g[i]
g[i]代表一个变量,存的是一个值,
g
(
i
)
g(i)
g(i)是一个精确的定义的函数,值不允许改变。
解释这个操作的意思,就是每次我们枚举
p
p
p以后的目的是,把所有的以
p
p
p为最小质因子的数,消除影响,就是减去他们的贡献,
g
(
p
−
1
)
∗
f
(
p
)
g(p-1)*f(p)
g(p−1)∗f(p)里面是所有的以
p
p
p为最大质因子的贡献,是减多了。在把他们加回来的操作。
需要注意一点的: g [ n ] g[n] g[n]在最初始的情况下,被填充的是 ∑ i = 2 n f ′ ( i ) = ∑ i = 2 n i k \sum_{i=2}^nf'(i)=\sum_{i=2}^ni^k ∑i=2nf′(i)=∑i=2nik.
回过头来看这个操作,假设我们枚举完了第 k k k个质数即 p k p_k pk,我们观察一下 g [ n ] g[n] g[n]里面的内容是什么,为方便起见,我们设为 g [ n ] k g[n]_k g[n]k: g [ n ] k = ∑ i = 1 k f ( p i ) + ∑ p k < x < = n [ x 没 有 前 k 个 质 因 子 ] ∗ f ( x ) g[n]_k=\sum_{i=1}^kf(p_i)+\sum_{p_{k}<x<=n}[x没有前k个质因子]*f(x) g[n]k=i=1∑kf(pi)+pk<x<=n∑[x没有前k个质因子]∗f(x)
设 P ′ = { p ∈ P , 且 p < = n } P'=\{p \in P,且p<=\sqrt n \} P′={p∈P,且p<=n}
则: g [ n ] ∣ P ′ ∣ = ∑ i = 1 ∣ P ′ ∣ f ( p i ) + ∑ p k < x < = n [ x 没 有 前 ∣ P ′ ∣ 个 质 因 子 ] ∗ f ( x ) g[n]_{|P'|}=\sum_{i=1}^{|P'|}f(p_i)+\sum_{p_{k}<x<=n}[x没有前|P'|个质因子]*f(x) g[n]∣P′∣=i=1∑∣P′∣f(pi)+pk<x<=n∑[x没有前∣P′∣个质因子]∗f(x)
显然,这里的 x x x都是质数,那么到这里: g [ n ] 等 于 g ( n ) g[n]等于g(n) g[n]等于g(n)
到这里真确性得以验证,到这里问题得到了理论上的解决。
关于复杂度:
温老师的ppt说每个可能用到的
g
(
i
)
g(i)
g(i),只会在遍历不超过
n
\sqrt n
n的质数访问到,因此,每个i贡献的时间复杂为
O
(
i
l
o
g
i
)
=
O
(
i
l
o
g
i
)
O(\frac{\sqrt i}{log \sqrt i})=O(\frac{\sqrt i}{log\ i})
O(logii)=O(log ii)
总时间复杂度为:
O
(
∑
i
=
1
n
i
l
o
g
i
+
∑
i
=
1
n
n
i
l
o
g
n
i
)
≈
O
(
n
3
4
l
o
g
n
)
O(\sum_{i=1}^{\sqrt n}\frac{i}{log\ i}+\sum_{i=1}^{\sqrt n}\frac{\sqrt \frac{n}{i}}{log\ \sqrt \frac{n}{i}})\approx O(\frac{n^{\frac{3}{4}}}{log\ n})
O(i=1∑nlog ii+i=1∑nlog inin)≈O(log nn43)
举个例子:
比如求 g ( 12 ) g(12) g(12),只要枚举2,3两个因子就可以了,
初始
g
[
12
]
=
∑
i
=
2
12
f
(
12
)
g[12]=\sum_{i=2}^{12}f(12)
g[12]=∑i=212f(12),(
g
[
1
]
=
0
g[1]=0
g[1]=0,显然)
枚举
2
2
2,则
g
[
12
]
−
=
(
g
[
6
]
−
g
[
1
]
)
∗
f
′
(
2
)
g[12]-=(g[6]-g[1])*f'(2)
g[12]−=(g[6]−g[1])∗f′(2)
那么:
g
[
12
]
=
f
′
(
2
)
+
f
′
(
3
)
+
f
′
(
4
)
+
f
′
(
5
)
+
f
′
(
6
)
+
f
′
(
7
)
+
f
′
(
8
)
+
f
′
(
9
)
+
f
′
(
10
)
+
f
′
(
11
)
+
f
′
(
12
)
g[12]=f'(2)+f'(3)+\sout{f'(4)}+f'(5)+\sout{f'(6)}+f'(7)+\sout{f'(8)}+f'(9)+\sout{f'(10)}+f'(11)+\sout{f'(12)}
g[12]=f′(2)+f′(3)+f′(4)+f′(5)+f′(6)+f′(7)+f′(8)+f′(9)+f′(10)+f′(11)+f′(12)枚举
3
3
3,则
g
[
12
]
−
=
(
g
[
4
]
−
g
[
2
]
)
∗
f
′
(
3
)
g[12]-=(g[4]-g[2])*f'(3)
g[12]−=(g[4]−g[2])∗f′(3),这时
g
[
4
]
=
f
′
(
2
)
+
f
′
(
3
)
g[4]=f'(2)+f'(3)
g[4]=f′(2)+f′(3),乘上
f
′
(
3
)
f'(3)
f′(3)以后,相当于把
f
′
(
6
)
f'(6)
f′(6)给多减了,因为枚举2时已经把
f
′
(
6
)
f'(6)
f′(6)减了,所以这里
g
[
2
]
=
f
′
(
2
)
g[2]=f'(2)
g[2]=f′(2),乘上
f
′
(
3
)
f'(3)
f′(3),又把
f
′
(
6
)
f'(6)
f′(6)加回来。
那么:
g
[
12
]
=
f
′
(
2
)
+
f
′
(
3
)
+
f
′
(
4
)
+
f
′
(
5
)
+
f
′
(
6
)
+
f
′
(
7
)
+
f
′
(
8
)
+
f
′
(
9
)
+
f
′
(
10
)
+
f
′
(
11
)
+
f
′
(
12
)
g[12]=f'(2)+f'(3)+\sout{f'(4)}+f'(5)+\sout{f'(6)}+f'(7)+\sout{f'(8)}+\sout{f'(9)}+\sout{f'(10)}+f'(11)+\sout{f'(12)}
g[12]=f′(2)+f′(3)+f′(4)+f′(5)+f′(6)+f′(7)+f′(8)+f′(9)+f′(10)+f′(11)+f′(12)
循环结束。
如有错误欢迎指正。