1. 程式人生 > >從狄利克雷卷積到杜教篩

從狄利克雷卷積到杜教篩

狄利克雷卷積

積性函式


定義:

對於數論函式\(f\),若對於任意互質的數\(x,y\),滿足\(f(x*y)=f(x)*f(y)\),則\(f\)為一個積性函式。


事實上,我們見過的大部分數論函式都是積性函式,常見的如:

  • \(\mu(x)\),莫比烏斯函式,在莫比烏斯反演有討論過。
  • \(\varphi(x)\),尤拉函式。
  • \(d(x)\),表示\(x\)的約數個數。
  • \(\sigma(x)\),約數和函式。
  • \(\epsilon(x)\),狄利克雷卷積的原函式,即\(\epsilon(x)=[x=0]\)
  • \(id(x)\),定義\(id(x)=x\)
  • \(I(x)\),定義\(I(x)\)函式值恆為\(1\),即\(I(x)=1\)

這只是一小部分,其中有些函式的性質待會會分析。


狄利克雷卷積


定義:

對於數論函式\(f\)\(g\),定義它們的狄利克雷卷積為:
\[ (f*g)(n)=\sum_{d|n}f(d)g(\frac{n}{d}) \]
其中\((f*g)\)表示\(f\)\(g\)的狄利克雷卷積。


然後有一個很重要的性質,對於積性函式\(f\)\(g\),它們的狄利克雷卷積也是個積性函式。

證明很簡單,設質數\(p\)\(n\)互質,則:
\[ (f*g)(np)=\sum_{d|np}f(d)g(\frac{np}{d}) \]


然後展開:
\[ (f*g)(np)=\sum_{d|n}f(d)g(\frac{np}{d})+\sum_{d|n}f(pd)g(\frac{n}{d}) \]
由於\(f,g\)為積性函式,可以拆開提出來:
\[ (f*g)(np)=(g(p)+f(p))\sum_{d|n}f(d)g(\frac{n}{d}) \]
注意到第一項就是\((f*g)(1)\),第二項為\((f*g)(n)\),所以:
\[ (f*g)(np)=(f*g)(n)*(f*g)(p) \]
命題得證。

根據這個,可以有效的判斷函式是否為積性函式。


狄利克雷卷積具有的一些性質:

  • 交換律:\(f*g=g*f\)
  • 結合律:\(f*(g*h)=(f*g)*h\)

證明很顯然,這裡就不贅述了。

然後考慮一些常見函式的狄利克雷卷積:


1.\(\epsilon(x)\)

對於任意數論函式\(f\),根據定義,拿一個捲上一個\(\epsilon\),得到:
\[ (f*\epsilon)(n)=\sum_{d|n}f(d)\epsilon(\frac{n}{d})=f(n) \]
\(f*\epsilon=f\)

然後我們可以驚奇的發現,卷完了之後得到了他本身,所以說這個函式就是狄利克雷卷積的單位元。


2.\(\mu(x)\)

首先我們知道這樣一個式子:
\[ \sum_{d|n}\mu(d)=[n=1] \]
寫成狄利克雷卷積形式就是:
\[ \mu*I=\epsilon \]


3.\(\varphi(x)\)

這個函式有一些很妙的性質,比如說(眾所周知):
\[ \sum_{d|n}\varphi(x)=n \]
證明如下:

\(f(n)=\sum_{d|n}\varphi(d)\),由上面提到的狄利克雷卷積性質可得,\(f\)為積性函式。

對於\(n\)的每一個質因數進行考慮,即:
\[ f(x^{p})=\sum_{d|x^p}\varphi(d)=\sum_{i=0}^p\varphi(x^i) \]
因為\(\varphi(x^p)=\varphi(x^{p-1})*p\)\(\varphi(x)=x-1\)可得:
\[ f(x^p)=x-1+\sum_{i=1}^p(x-1)*x^{i} \]
由等比數列求和可得\(f(x^p)=x^p\),又由\(f\)為積性函式可得\(f(n)=n\),得證。

寫成狄利克雷卷積的形式就是:
\[ \varphi*I=id \]
然後注意到\(\mu*I=\epsilon\),於是嘗試在等式兩邊分別捲上一個\(\mu\)
\[ \begin{align} \varphi*(I*\mu)&=id*\mu\\ \varphi*\epsilon&=id*\mu\\ \mu*id&=\varphi \end{align} \]
寫成一般形式就是:
\[ \sum_{d|n}\mu(d)*\frac{n}{d}=\varphi(n) \]
這個式子也很常用的。

杜教篩

前置知識終於講完了

對於積性函式\(f\),現在考慮求\(\sum_{i=1}^nf(i)\)

當然我知道你會線篩,但是有一些小清新(無良)出題人把資料開到\(1e9\)級別,你就做不了了,所以需要更快的演算法。

\(S(n)=\sum_{i=1}^{n}f(i)\)

考慮先拿一個函式和\(f\)做卷積,先不考慮這個函式是啥,先設它為\(g\),則:
\[ (f*g)(n)=\sum_{d|n}^{n}f(d)g(\frac{n}{d}) \]
對這個函式字首和一下:
\[ \sum_{i=1}^n\sum_{d|i}g(d)f(\frac{n}{d})=\sum_{d=1}^{n}g(d)\sum_{i=1}^{\lfloor\frac{n}{d}\rfloor}f(i)=\sum_{d=1}^{n}g(d)S(\lfloor\frac{n}{d}\rfloor) \]
中間交換求和符號就不贅述了。

然後有一個很顯然的式子:
\[ g(1)S(n)=\sum_{d=1}^{n}g(d)S(\lfloor\frac{n}{d}\rfloor)-\sum_{d=2}^{n}g(d)S(\lfloor\frac{n}{d}\rfloor) \]
然後把等號右邊第一項換一下:
\[ S(n)=\sum_{i=1}^{n}(f*g)(i)-\sum_{d=2}^{n}g(d)S(\lfloor\frac{n}{d}\rfloor) \]
剩下的事情就很顯然了,如果我們能湊出一個\(g\),使得它和\(f\)的卷積的字首和很好算,它也很好算,我們就可以先預處理出前\(1e7\)左右的資料,然後記憶化遞迴處理\(S\)

至於\(g\),因題目不同而不同,做多了也就有經驗了。

注意上試是杜教篩的套路試子,如果不會推也沒關係,記下來就好了。

這裡還是舉幾個栗子吧:

1.\(\sum_{i=1}^{n}\mu(i)\).

首先我們知道一個這樣的東西:
\[ \mu*I=\epsilon \]
對於\(\epsilon\)的字首和,顯然是\(1\)

所以,令\(g(n)=I(n)=1\),得到:
\[ S(n)=1-\sum_{i=2}^nS(\frac{n}{i}) \]
然後數論分塊下就行了。

程式碼也很簡單,記住一定要記憶化。

map<int,int > Mu;
int sum_mu(int n) {
    if(n<maxn) return mu[n];
    if(Mu[n]) return Mu[n];
    int T=2,res=1;
    while(T<=n) {
        int pre=T;T=n/(n/T);
        res=res-(T-pre+1)*sum_mu(n/T);T++;
    }
    return Mu[n]=res;
}

2.\(\sum_{i=1}^{n}\varphi(i)*i\)

這次考慮一個難一點的。

我們的目的是要找一個\(g\),使他們捲起來很好算。

那麼先列出式子:
\[ (f*g)(n)=\sum_{i|n}i*\varphi(i)*g(\frac{n}{i}) \]
然後發現中間有個\(i\)的係數,可以考慮消去它,於是暫且令\(g(n)=n\)
\[ (f*g)(n)=\sum_{i|n}n*\varphi(i)=n^2 \]
然後可以發現這個東西非常好算,因為:
\[ \sum_{i=1}^{n}i^2=\frac{n(n+1)(2n+1)}{6} \]
所以:
\[ S(n)=\frac{n(n+1)(2n+1)}{6}-\sum_{i=2}^{n}i*S(\frac{n}{i}) \]

總結

對於一個陌生的函式,如果要求字首和,先判是不是積性函式,然後通過這個函式的性質進行分析湊\(g\),也可以像慄2一樣湊,實在不行就一個一個試。

當然有時候線篩也是很好的,或者可以列舉因數大力算,不要總是糾結於能不能杜教篩。

習題

[bzoj3944] Sum

[bzoj4176] Lucas的數論

[bzoj4916] 神犇和蒟蒻

[bzoj4652]|[Noi2016]迴圈之美(挖坑)

[bzoj3930] [CQOI2015]選數