您的位置:首页 > 其它

51nod 最大公约数 & 最小公倍数

2016-11-10 13:28 218 查看
之前学习杜教筛的时候,把 φ 和 μ 的前缀和两道题做过之后就没有再深入学习…NOI D1T3 看出来是杜教筛但是不会推只好做一个被唾弃的暴力选手…越来越觉得自己数论姿势太naive,所以补一补稍稍高端的知识。。。从刷经典题开始吧

前置技能(杜教筛)简介:

我们记 f∘g 表示数论函数 f 和 g 的 Dirichlet 卷积,下同。

要计算 f(i) 的前缀和(记为 F(i) ),考虑构造新的函数 g(i),使得 h=f∘g 的前缀和易于计算,那么我们有:

∑i=1nh(i)=∑i=1n∑ab=if(a)×g(b)=∑ab≤nf(a)×g(b)=∑b=1ng(b)×F(⌊nb⌋)

这里蕴含着一个关于 F(n) 的递推式,如果能快速计算 ∑ni=1h(i) 和 g(i) 的值,同时预处理 i≤n23 的 F(i),那么 F(n) 的计算可以被优化到 O(n23)

最大公约数之和V3

题意:给定 n,计算 ∑ni=1∑nj=1(i,j)。(n≤1011)。

sol:

我们令 A(n)=∑ni=1(i,n),则答案等于 2×∑ni=1A(i)−∑ni=1i,这个分 i<j, i=j, i>j 讨论就能得出。

现在的问题是:如何快速计算 A(n) 的前缀和?

考虑化简 A(n),枚举 (i,n),我们有:

A(n)=∑d|nd×φ(nd)

显然这是个积性函数,并且知道它是 id 和 φ 的 Dirichlet 卷积,因为我们有:

φ=id∘μ

所以

id∘φ=id∘id∘μ

id∘φ∘1=id∘id

如果能够快速计算 id∘id 的前缀和,那么套用杜教筛,就能快速算出 A(n) 的前缀和。

记 A(n) 的前缀和为 S(n),id∘id 的前缀和为 H(n)

H(n)=∑i=1ni⌊ni⌋(⌊ni⌋+1)

这个显然是可以分块计算的。

使用杜教筛,我们总共需要计算 O(n√) 项 S(i) ,可以使用线性筛预处理出来 i≤n23 的S(i)。对于每一个 i>n23 的 S(i),我们 O(i√) 地计算它对应的 H(i)。因为我们计算 S(i) 时需要枚举 O(i√) 个 更小的 S(j),而计算 H(i) 的时间消耗也是 O(i√)。所以暴力计算这些 H(i) 不会使复杂度的阶升高,可以保证总的时间复杂度为 O(n23)

题外话:用这种做法交上去,最慢的点大概需要 2.3s 左右。A掉之后我去观摩了一下 1s 的神牛们的写法,发现非常 excited :

注意到:

S(n)=∑i=1n∑j|ij×φ(ij)=∑ij≤ni×φ(j)=∑i=1ni∑j=1⌊ni⌋φ(j)

于是按照 ⌊ni⌋ 分块计算一个 φ(i) 的前缀和就好了。。。我真是思博啊。。。

最小公倍数之和 V3

题意:给定 n,计算 ∑ni=1∑nj=1[i,j]。(n≤1011)。

sol :

同样的,考虑计算 ∑ni=1[i,n],记为 A(n),同样的枚举 (i,n):

A(n)=n∑d|n∑(i,nd)=1i

注意到 n>1 时,”小于n且与n互质的数” 的和为 n×φ(n)2,对于 n=1 的情况特殊讨论,上式又可以简化为:

A(n)=n2∑d|nd×φ(d)+n2

后一项的前缀和即为 n×(n+1)4,以下讨论式子前一项的做法:

记 f(n)=n∑d|nd×φ(d),f(n) 的前缀和为 F(n)。考虑如何计算 F(n)

把 n “分配” 到和式中去,我们有:

f(n)=∑ab=na2φ(a)×b

注意到这是 id2⋅φ 和 id 的 Dirichlet 卷积,我们进一步地推导:

注意到 (id2⋅φ)∘id2=id3,即:

∑ab=na2φ(a)×b2=n2∑a|nφ(a)=n3

那么我们有:

id2∘(id2⋅φ)∘id=id3∘id

同样地,我们记 id3∘id 的前缀和为 H(n),那么:

H(n)=∑i=1i∑j=1⌊nd⌋j3

这个也可以分块计算,同上一题的复杂度分析,这道题我们也能得到一个 O(n23) 的做法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: