51nod 最大公約數 & 最小公倍數

之前學習杜教篩的時候,把 φμ 的前綴和兩道題做過之後就沒有再深入學習…NOI D1T3 看出來是杜教篩但是不會推只好做一個被唾棄的暴力選手…越來越覺得自己數論姿勢太naive,所以補一補稍稍高端的知識。。。從刷經典題開始吧

前置技能(杜教篩)簡介:

我們記 fg 表示數論函數 fg 的 Dirichlet 卷積,下同。

要計算 f(i) 的前綴和(記爲 F(i) ),考慮構造新的函數 g(i) ,使得 h=fg 的前綴和易於計算,那麼我們有:

i=1nh(i)=i=1nab=if(a)×g(b)=abnf(a)×g(b)=b=1ng(b)×F(nb)

這裏蘊含着一個關於 F(n) 的遞推式,如果能快速計算 ni=1h(i)g(i) 的值,同時預處理 in23F(i) ,那麼 F(n) 的計算可以被優化到 O(n23)

最大公約數之和V3

題意:給定 n ,計算 ni=1nj=1(i,j) 。(n1011 )。

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φ=ididμ

idφ1=idid

如果能夠快速計算 idid 的前綴和,那麼套用杜教篩,就能快速算出 A(n) 的前綴和。

A(n) 的前綴和爲 S(n)idid 的前綴和爲 H(n)

H(n)=i=1nini(ni+1)

這個顯然是可以分塊計算的。

使用杜教篩,我們總共需要計算 O(n)S(i) ,可以使用線性篩預處理出來 in23S(i) 。對於每一個 i>n23S(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=1nj|ij×φ(ij)=ijni×φ(j)=i=1nij=1niφ(j)

於是按照 ni 分塊計算一個 φ(i) 的前綴和就好了。。。我真是思博啊。。。

最小公倍數之和 V3

題意:給定 n ,計算 ni=1nj=1[i,j] 。(n1011 )。

sol :

同樣的,考慮計算 ni=1[i,n] ,記爲 A(n) ,同樣的枚舉 (i,n)

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

注意到 n>1 時,”小於n 且與n 互質的數” 的和爲 n×φ(n)2 ,對於 n=1 的情況特殊討論,上式又可以簡化爲:

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

後一項的前綴和即爲 n×(n+1)4 ,以下討論式子前一項的做法:

f(n)=nd|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=n2a|nφ(a)=n3

那麼我們有:

id2(id2φ)id=id3id

同樣地,我們記 id3id 的前綴和爲 H(n) ,那麼:

H(n)=i=1ij=1ndj3

這個也可以分塊計算,同上一題的複雜度分析,這道題我們也能得到一個 O(n23) 的做法。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章