1. 程式人生 > >線性篩與莫比烏斯反演

線性篩與莫比烏斯反演

然而 效率 復雜度 是把 套路 組合數 處理 for 答案

線性篩與莫比烏斯反演

和上篇文章一樣,一直沒有研究這個東西,結果又考了GG……TAT
下定決心學一學,搞好這個東西。

線性篩

篩質數有很多方法,好像很厲害的有洲閣篩、杜教篩(然而我都不會QAQ),比較坑的有暴力篩(就是枚舉一個數的倍數)。
我只學了比較簡單而且實用的線性篩法。
這種篩法是避免一個數被重復篩幾遍,所以效率均攤下來可以達到線性。(網上有證明)

先上代碼:

const int N = 100000;
bool is_prime[N+100];
int prime[N], cnt = 0;
void find_prime() {
    Set(is_prime, true);
    is_prime[0
] = is_prime[1] = false; For(i, 2, N) { if (is_prime[i]) prime[++cnt] = i; For(j, 1, cnt) { if (i * prime[j] > N) break; is_prime[i * prime[j] ] = false; if (i % prime[j] == 0) break; //here } } }

這個代碼有一個關鍵點 就是上面的\(here\)

這個意義就是
對於一個合數\(m\)可以分解為\(m=p_1^{r_1}*...*p_n^{r_n}\)其中
\(p_i\)為質數,那麽我們篩\(m\)的時候之前把\(p_1\)篩掉了,所以在
枚舉\(i\)的時候。

  1. 如果\(i\)為素數沒問題,直接向後繼續推(因為篩出的
    質數都類似\(m=p_1*p_2\)的形式,所以不可能重復)。

  2. 如果為合數,那麽\(i\)可以分解成\(i=p_1^{r_1}*...*p_n^{r_n}\)形式
    其中\(p_1-p_n\)是遞增的,那麽\(p_1\)是最小的那個質數。\(i \bmod p_1 = 0\)的時候,就不用繼續枚舉了,
    所以我們就只能篩出不大於\(p_1\)

    的質數\(*i\)

莫比烏斯反演

莫比烏斯反演很多時候都能大大簡化運算……

  • 定理:\(F(n)\)\(f(n)\)是定義在非負整數集合上的兩個
    函數,並且滿足條件\(F(n)=\sum \limits \limits _{d|n}{f(d)}\)。那麽我們
    就能得到結論:

\(f(n)=\sum \limits \limits _{d|n}\mu(d)F(\frac{n}{d})\)


在上面的公式中有一個\(\mu(d)\)函數,它的定義如下:

(1)若\(d=1\),那麽\(\mu(d)=1\)

(2)若\(d=p_1p_2...p_k\)\(p_i\)均為互異質數,
那麽\(\mu(d)=(-1)^{k}\)。這個我的理解就是\(d\)
質因數個數為偶數的話,那麽\(\mu(d)=1\)否則為\(-1\)

(3)其他情況下\(\mu(d)=0\)這個就是對上面那條的拓展了,
就是指的\(d\)沒有一個平方因子,或者說沒有一個質因子的
次數大於\(1\)

線性篩求莫比烏斯函數的代碼:

const int N = 100100;
bool is_prime[N+100];
int mu[N+100] = {0, 1}, cnt = 0, prime[N+100];
void init() {
    Set(is_prime, true);
    is_prime[1] = false;
    For (i, 2, N) {
        if (is_prime[i]) {
            prime[++cnt] = i;
            mu[i] = -1; //質數的質因子個數肯定為奇數個就是1
        }
        For (j, 1, cnt) {
            if (i * prime[j] > N) break;
            is_prime[i * prime[j] ] = false;
            if (i % prime[j]) mu[i * prime[j] ] = -mu[i]; //多了一個質因子直接變為原來結果的相反數
            else {
                mu[i * prime[j]] = 0; //這個將要被篩的數至少具有兩個prime[j]的因子
                break;
            }
        }
    }
}

有了上面的知識,現在,我們來證明莫比烏斯反演定理。

證明:

\(\sum \limits _{d|n}\mu(d)F(\frac{n}{d})=\sum \limits_{d|n}\mu(d)\sum \limits_{d‘|\frac{n}{d}}f(d‘) =\sum \limits \limits _{d‘|n}f(d‘)\sum \limits_{d|\frac{n}{d‘}}\mu(d)=f(n)\)


Q.E.D

  • 然後還要提一下的就是一些常見的定理,證明嘛……
  • 一般都是先分解質因數,然後再根據組合數性質去算,比如第一個。
  • 要麽就是對於一些常見的反演格式進行反演,比如第二個。

  • \(\sum \limits _{d|n} \mu(d)=[n=1]\)
  • \(\sum \limits _{d|n} \frac{\mu(d)}{d}=\frac{\varphi(n)}{n}\)


一些例題(難題)

  • Luogu 【P1829】[國家集訓隊]Crash的數字表格

  • 題意

    \(\sum \limits _{i=1}^{n} \sum \limits_{i=1}^{m} lcm(i,j) \ (n,m \le 10^7)\)

  • 題解

    一個莫比烏斯反演然後化式子。

\(\sum \limits \limits _{i=1}^{n} \sum \limits_{i=1}^{m} lcm(i,j)\)

\(=\sum \limits \limits _{i=1}^{n} \sum \limits_{i=1}^{m} \frac{i\ j}{gcd(i,j)}\)

\(=\sum \limits \limits _{d=1}^{min(n,m)} \ d \sum \limits_{i=1}^{\lfloor \frac{n}{d} \rfloor} \sum \limits_{j=1}^{\lfloor \frac{m}{d} \rfloor} \ ij \ [gcd(i,j)=1]\)

這個就是一個更換枚舉相的操作了,是個套路。
你先枚舉所有可能的\(gcd\)再計算這種\(gcd\)的貢獻。

比如前面的那個\(d\)就是我們枚舉的\(gcd\),後面所有可能的數對,就是在\(\lfloor \frac{n}{d} \rfloor\)\(\lfloor \frac{m}{d} \rfloor\)中的所有互質的數對的乘積在乘上\(d\)

這個可以簡單理解一下,就是兩個數分別除以他們的最大公因數,然後兩個數肯定是互質的。
但其對於答案的貢獻就多除以了一個\(d\),所以要乘回來。

\(ans =\sum \limits _{d=1}^{min(n,m)} \ d \sum \limits_{i=1}^{\lfloor \frac{n}{d} \rfloor} \sum \limits_{j=1}^{\lfloor \frac{m}{d} \rfloor} \sum \limits_{x|gcd(i,j)}\mu(x) * i * j\)

這個就是運用了前面的公式\(\sum \limits _{d|n} \mu(d)=[n=1]\)來替代了\([gcd(i,j)=1]\)的條件。(這個就是套路了)

然後我們繼續推:

\(ans =\sum \limits \limits _{d=1}^{min(n,m)} d \sum \limits_{x=1}^{min(\lfloor \frac{n}{d} \rfloor,\lfloor \frac{m}{d} \rfloor)} \mu(x) \ x^2 \sum \limits_{i=1}^{\lfloor \frac{n}{dx} \rfloor} i \sum \limits_{j=1}^{\lfloor \frac{m}{dx} \rfloor} j\)

這個也是套路,把\(x\)提前了。就是改成了枚舉\(x\)看看它的對於答案的貢獻是多少。
很容易發現,就是在\([1,\lfloor \frac{n}{dx} \rfloor]\)中的所有數乘上\(x\)
就是原來可行的\(i\)。然後我們就可以根據這個來優化了。

前面那兩個\(\sum \limits\)就是\(n \ ln \ n\)(令\(n=max(n,m)\))的復雜度。(就是\(\sum \limits \limits _{i=1}^{n} \frac{n}{i}\))。後面的那兩個,直接用等差數列求和公式\(O(1)\)算。

但這個仍然過不去...(\(O(1.61*10^8)\),$ % $的常數還很大)所以就需要來用套路的整除分塊了。
就是把後面兩個 \(\sum \limits\) 很多一樣答案的地方一起處理掉,所以對於那個 \(\mu(x) \ x^2\) 還要記一個前綴和。

總復雜度\(O(\sum \limits _{i=1}^{n} \sqrt{\frac{n}{i}})=O(pass)\)這個我也不會算。。大佬說似乎是\(O(n^{\frac{2}{3}})\)

線性篩與莫比烏斯反演