數論函數 - 莫比烏斯函數與莫比烏斯反演 - 基礎杜教篩


 原文鏈接http://www.cnblogs.com/zhouzhendong/p/8627380.html

省選后發現我數學好差。於是先從數論開始學習。

如果發現本文有任何錯誤,歡迎留言指正。

本文內容大致如下:

  • 數論函數基礎知識
  • 狄利克雷卷積與莫比烏斯反演
  • 杜教篩
  • 例題

 

數論函數基礎知識

幾個定義

  • 數論函數:定義域為正整數的函數。(默認下面提到的函數全部都是數論函數)
  • 積性函數:如果$a,b$滿足$gcd(a,b)=1$,則$f(ab)=f(a)f(b)$。
  • 完全積性函數:對於任何$a,b$,滿足$f(ab)=f(a)f(b)$。

 

幾個積性函數

  $1.$歐拉函數:$\varphi(n)=\large\sum_{i=1}^{n}[gcd(i,n)=1]$,是積性函數。

  $2.$莫比烏斯函數:$\large\mu$ 當$n$有平方因子的時候,$\mu(n)=0$,否則設$n$為$k$個不同質因子的積,則$\mu(n)=(-1)^{k}$。

  $3.$除數函數:這不是完全積性函數。$\sigma_{a}n=\sum_{d|n}d^{a}$。其中$d(n)=\sigma_{0}(n)$為$n$的因數個數,$\sigma_{1}(n)=\sigma(n)$為$n$的所有因數之和。

  $4.$冪函數:這是完全積性函數。$id_k(n)$,表示$n^k$。

  $5.$單位函數:這是完全積性函數。$e(n)=[n=1]$。

 

 Dirichlet卷積

 定義

  函數$f$與$g$的Dirichlet卷積定義如下:

  $$(f*g)(n)=\sum_{d|n}f(d)\times g(\frac{n}{d})$$

   個人認為看起來比較舒服的寫法:

  $$(f*g)(n)=\sum_{ij=n}f(i)\times g(j)$$

  於是,就很容易發現:

  $$(f*g*h)(n)=\sum_{ijk=n}f(i)\times g(j)\times h(k)$$

 

幾點性質

  交換律:略

  結合律:略

  分配律:$f*(g+h)=f*g+f*h$

  單位元:$f*e=f$

 

  如果$f,g$都為積性函數,那么$f*g$也為積性函數。

  對於任何一個函數$f$,則一定存在一個函數$g$滿足$f*g=e$,則$g$叫做$f$的Dirichlet逆。

 

  計算Dirichlet卷積。

設$h=f*g$

計算$h(n)$:

  顯然直接根據定義,枚舉因數即可。時間復雜度$O(\sqrt n)$。

 

h(n)=0;
for (int i=1;i*i<=n;i++){
    if (n%i)
        continue;
    h(n)+=f(i)*g(n/i);
    if (i*i!=n)
        h(n)+=f(n/i)*g(i);
}

 

  

 

計算$h$,其中$h$的定義域為正整數$1$~$n$。

  顯然$O(\sqrt n)$太慢了。於是:

  經典簡單套路。先枚舉一個數i,然后再枚舉倍數。時間復雜度$O(n\ log\ n)$。

memset(h,0,sizeof h);
for (int i=1;i<=n;i++)
    for (int j=1;i*j<=n;j++)
        h(i*j)+=f(i)*g(j);

 幾個Dirichlet卷積

  除數函數卷上1。($1=id_0$)

  $$d(n)=\sum_{d|n}1\Rightarrow d=1*1$$

  $$\sigma(n)=\sum_{d|n}d\Rightarrow \sigma=id*1$$

 

  莫比烏斯函數與1的卷積。

  (我一開始制杖了,好久沒看懂。)

  其中$k$為$n$的不同種類的質因數個數。

  $$\sum_{d|n}\mu(n)=\sum_{i=0}^{k}(-1)^i\times \binom{k}{i}=(1-1)^{k}=0^{k}$$

  其中,對於$0^0$沒有定義。但是考慮到滿足$k=0$的只有$n=1$,而$\mu(1)=1$,所以:

  $$\sum_{d|n}\mu(n)=[n=1]=e(n)$$

  於是就有:

  $$e=\mu*1$$

  這個對於之后的莫比烏斯反演十分重要,請務必記住。

 

  另一個常用的卷積:

  $$\varphi*1=??$$

  考慮到,若$d$為$n$的因數,則$\varphi(d)$即與$n$的最大公約數為$\frac{n}{d}$的數的個數。所以:

  $$\sum_{d|n}\varphi(d)=n$$

  $$\Longrightarrow \varphi*1=id$$

 

  關於冪函數:

  $$id_k\times(a*b)=(id_k\times a)*(id_k\times b)$$

  $$(\varphi\times id_k)*id_k=id_{k+1}$$

 

莫比烏斯反演

莫比烏斯函數的一個重要性質

  考慮前文提到的

  $$e=\mu*1$$

  這個式子也說明了$\mu$和$1$在Dirichlet卷積的意義下互為逆元。

  於是我們就可以通過這個來反演了。

因數反演

  已知$g=f*1$,讓你用$g$函數的式子來表示$f$。

  $$g(n)=\sum_{d|n}f(d)$$

  考慮到兩邊同時在Dirichlet卷積的意義下除以$1$。而$\mu$和$1$在Dirichlet卷積意義下互為逆元,所以除$1$可以卷上$\mu$代替。

  $$g=f*1\Longrightarrow f=g*\mu$$

  不服??看下面的推導。

  $$f*1=g\Longrightarrow f*1*\mu=g*\mu\Longrightarrow f*e=g*\mu\Longrightarrow f=g*\mu$$

倍數反演

  這個嘛,大概得注重一下函數的具體定義域。

  $$g(n)=\sum_{n|d}f(d)\Longrightarrow f(n)=\sum_{n|d}\mu(\frac{d}{n})g(d)$$

 

套路套路!!

一句話的套路

  1. 枚舉gcd的取值。

  2. 交換倍數和約數。

  3. 用莫比烏斯函數求和替換$[a=1]$這種表達式。

  4. 改寫求和指標。

  5. 整除分塊。

一些較為具體的套路(反正都是套路,數學推導能力極強的dalao可以不記……)

  一、計算函數$f$與$1$的Dirichlet卷積的某一項。即$g=f*1$,求$g(n)(n\leq 10^{18})$。

    1. 我們對$n$進行質因數分解,使用Pollard_rho算法,復雜度$O(n^{\frac{1}{4}}\log n)$。

    2. 設$n=\prod_{i=1}^{t}p_i^{k_i}$,$g(n)=\sum_{d|n}f(d)$,請您自行推導下面的公式(時間復雜度$O(log\ n)$):

      $$g(n)=\prod_{i=1}^{t}\sum_{j=0}^{k_i}f(p_i^j)$$

 

  二、整除分塊。求$f(n)=\sum_{i=1}^{n}g(i)\times\left\lfloor\frac{n}{i}\right\rfloor$。

    1. 考慮到$\left\lfloor\frac{n}{i}\right\rfloor$只有$O(\sqrt n)$種取值。對於相同的$\left\lfloor\frac{n}{i}\right\rfloor$,$i$的取值范圍為:

    $$\Large \left[\left\lfloor\frac{n}{\left\lfloor\frac{n}{i}\right\rfloor+1}\right\rfloor+1,\left\lfloor\frac{n}{\left\lfloor\frac{n}{i}\right\rfloor}\right\rfloor\right]$$

    2. 通過預處理函數$g$的前綴和,做到$O(1)$算函數$g$的區間和,整個求$f$就可以在$O(\sqrt n)$解決。

    3. 同時有$n,m$也類似,讀者可以自行推導。

 

  三、

    $$\varphi(n)=\sum_{d|n}\mu(d)\times\frac{n}{d}\Longrightarrow\varphi=\mu*id$$

    推導??

    先回憶一下之前提到的兩個Dirichlet卷積。

    $$e=\mu*1$$

    $$id=\varphi*1$$

    於是

    $$\varphi*1=id\\ \Longrightarrow \varphi*1*\mu=id*\mu\\ \Longrightarrow\varphi*e=id*\mu\\ \Longrightarrow\varphi=\mu*id$$

    

    啊,我是不是又推了一遍莫比烏斯反演??

    對莫比烏斯反演還是不熟悉的同學們注意了,上面的那個是$\varphi$的莫比烏斯反演,注意一下。

  

  四、注意注意!!莫比烏斯反演經典套路!!

    現在有個積性函數$f(n)$,設$n<m$,則:

    

    於是原來的式子就變成了求$f*\mu$了,再用上整數分塊就可以快速搞定了。

    UPD(2019-02-24): 突然想起來補了這段話。

      至少在我寫這個課件的時候及以前,我的想法是:

 

    直到我看見了這個……

(圖片來自  《炫酷的反演魔術》—— VFleaKing)

 

杜教篩

問題模型

  給定一個函數$f(n)$(例如$\varphi,\mu$),然后讓你求$S(n)=\sum_{i=1}^{n}f(i)$的值(有模數)$n\leq 10^{10}$。

構造

   直接求出$S(n)$會十分困難,所以我們考慮構造一個函數$g$,使得$f*g$的前綴和非常好求。

  $$\sum_{i=1}^{n}\sum_{j|i}f(i)g(\frac{i}{j})=\sum_{ij\leq n}f(i)g(j)=\sum_{i=1}^{n}g(i)S\left(\left\lfloor\frac{n}{i}\right\rfloor\right)$$

  $$g(1)S(n)=\sum_{ij\leq n}f(i)g(j)-\sum_{i=2}^{n}g(i)S\left(\left\lfloor\frac{n}{i}\right\rfloor\right)$$

一些補充

  於是我們就可以直接記憶化dfs搞定了。

  但是復雜度可以更好。

  我們考慮先預處理$k$個前綴和。時間復雜度$O(k+\frac{n}{\sqrt k})$。

  於是取$k=n^{\frac{2}{3}}$,復雜度為$O(n^{\frac{2}{3}})$。

  考慮到
  $$\left\lfloor\frac{n}{ab}\right\rfloor=\left\lfloor\frac{\left\lfloor\frac{n}{a}\right\rfloor}{b}\right\rfloor$$

  所以,由於$\frac{n}{n^{\frac{2}{3}}}=n^{\frac{1}{3}}$,所以會被算到的$S(i)$只有$O(n^{\frac{1}{3}})$個。

  這邊還有一個重要套路。

  存$S(i)$不是要hash嗎??直接把$S(i)$放到$f(n/i)$里面就可以了。

  你可以考慮一下$f=\varphi$或者$f=\mu$的情況。此時可以取$g=1$。

  當然$f$可能會是更加復雜的函數,於是你就要對應的找比較好的$g$了。

 

 一些例題

僅用積性函數性質進行推導:

BZOJ3560 DZY loves math V

 

莫比烏斯函數與莫比烏斯反演(套路)

BZOJ3561 DZY loves math VI

51Nod1675 序列變換

BZOJ4816 [Sdoi2017]數字表格

 

杜教篩

BZOJ3944 sum


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM