积性函数的性质及证明 + 线性筛

引言

在数论问题中,积性函数有着广泛的应用。
如在莫比乌斯反演问题中,函数变换之后如何快速维护前缀和往往是最重要也是最难的一步。如果维护的函数具有积性,那就可以尝试利用线性筛在 O ( n ) O(n) O(n)的时限内完成预处理,从而达到优化复杂度的神奇作用。
本文的大部分相关性质及公式来自:《线性筛与积性函数》- 贾志鹏
博主将试着证明其中的性质公式,严谨性可能欠缺,其目的主要是帮助大家理解并记忆


积性函数的定义和性质

定义: 对于一个定义域为 N + N^{+} N+的函数 f f f,对于任意两个互质的正整数 a , b a,b a,b,均满足 f ( a b ) = f ( a ) f ( b ) f(ab)=f(a)f(b) f(ab)=f(a)f(b),则称函数 f f f为积性函数
若对于任意整数 a , b a,b a,b都有 f ( a b ) = f ( a ) f ( b ) f(ab) = f(a)f(b) f(ab)=f(a)f(b),则函数 f f f被称为完全积性函数。

性质
(1)对于任意积性函数 f f f,均有 f ( 1 ) = 1 f(1) = 1 f(1)=1

证明:因 1 1 1与任何数都互质,假设存在一个正整数 a a a满足 f ( a ) ! = 0 f(a)!=0 f(a)!=0,故由定义: f ( a ) = f ( 1 ∗ a ) = f ( 1 ) f ( a ) f(a) = f(1*a) = f(1)f(a) f(a)=f(1a)=f(1)f(a)
f ( a ) f(a) f(a)不为 0 0 0,故等号两端同时消去一个 f ( a ) f(a) f(a),得:
f ( 1 ) = 1 f(1) = 1 f(1)=1
证毕。

(2)对于一个大于 1 1 1的正整数N,设 N = ∏ p i a i N = \prod p_i^{a_i} N=piai p i p_i pi为互不相同的素数。那么对于一个积性函数 f f f来说,有:
f ( N ) = f ( ∏ p i a i ) = ∏ f ( p i a i ) f(N) = f(\prod p_i^{a_i}) = \prod f(p_i^{a_i}) f(N)=f(piai)=f(piai)
f f f完全积性,则 f ( N ) = ∏ f ( p i ) a i f(N) = \prod f(p_i)^{a_i} f(N)=f(pi)ai

证明:由积性和完全积性的定义易得。


欧拉函数 φ \varphi φ

定义:对于正整数 n n n φ ( n ) \varphi(n) φ(n)是小于n的正整数中与n互质的个数。

定义式:若 n = ∏ p i a i n = \prod p_i^{a_i} n=piai
φ ( n ) = n ∏ ( 1 − 1 p i ) \varphi(n) = n \prod(1 - \frac{1}{p_i}) φ(n)=n(1pi1)

性质
(1)欧拉函数为积性函数,而不是完全积性函数。

证明:设两个互质的正整数 n , m n,m n,m
则:
φ ( n ) = n ∏ ( 1 − 1 p i ) \varphi(n) = n \prod(1 - \frac{1}{p_i}) φ(n)=n(1pi1)
φ ( m ) = m ∏ ( 1 − 1 p i ′ ) \varphi(m) =m \prod(1 - \frac{1}{p'_i}) φ(m)=m(1pi1)
φ ( n ) φ ( m ) = n ∏ ( 1 − 1 p i ) m ∏ ( 1 − 1 p i ′ ) = n m ∏ ( 1 − 1 p i ) ( 1 − 1 p i ′ ) \varphi(n)\varphi(m) = n \prod(1 - \frac{1}{p_i})m \prod(1 - \frac{1}{p'_i}) = nm\prod(1 - \frac{1}{p_i})(1 - \frac{1}{p'_i}) φ(n)φ(m)=n(1pi1)m(1pi1)=nm(1pi1)(1pi1)
n , m n,m n,m互质,故 p i , p i ′ p_i,p'_i pi,pi 各不相同,且均为 n m nm nm的质因子。

故推出:
φ ( n m ) = φ ( n ) φ ( m ) \varphi(nm) = \varphi(n)\varphi(m) φ(nm)=φ(n)φ(m)
积性函数性质得证。
而完全积性由上证明可见, n , m n,m n,m互质是一个严格且不可或缺的条件,可见,欧拉函数不是完全积性函数。

(2)假设存在一个素数 p p p和一个正整数 k k k,则: φ ( p k ) = p k − p k − 1 \varphi(p^k) = p^k - p^{k-1} φ(pk)=pkpk1
证明:

可以从反面来思考这件事,在小于 p k p^k pk且与其不互质的数有以下形式:
p ∗ 1 , p ∗ 2 , . . . p ∗ ( p k − 1 − 1 ) p*1,p*2,...p*(p^{k-1} - 1) p1,p2,...p(pk11)(因为p是唯一的质因子)

故由定义: φ ( p k ) = \varphi(p^k) = φ(pk)=总数 - 不互质的数 = ( p k − 1 ) − ( p k − 1 − 1 ) = p k − p k − 1 (p^k-1) - (p^{k-1} -1) = p^k - p^{k-1} (pk1)(pk11)=pkpk1
证毕。

另外还可以从定义式出发去理解这个结论。
φ ( p k ) = p k ( 1 − 1 p ) = p k − p k − 1 \varphi(p^k) = p^k(1-\frac{1}{p}) = p^k - p^{k-1} φ(pk)=pk(1p1)=pkpk1

(3)欧拉定理:若有互质的两个正整数 a , n a,n a,n,则有 a φ ( n ) ≡ 1 ( m o d   n ) a^{\varphi(n)} \equiv 1(mod \ n) aφ(n)1(mod n)
此定理常用来求解逆元。

证明:(可参考百度百科)

(4)假设存在一个正整数n,则: ∑ d ∣ n φ ( d ) = n \sum_{d|n} \varphi(d) = n dnφ(d)=n

证明:
先考虑特殊情况: n = 1 n = 1 n=1 φ ( 1 ) = 1 \varphi(1) = 1 φ(1)=1 显然成立
对于一般情况, n n n一定可以质因数分解为: n = p 1 a 1 p 2 a 2 . . . p k a k n = p_1^{a_1}p_2^{a_2}...p_k^{a_k} n=p1a1p2a2...pkak

当n只含一个质因子时,即 n = p a n = p^a n=pa
有:
∑ d ∣ n φ ( d ) = ∑ i = 0 a φ ( p i ) = 1 + ∑ i = 1 a ( p i − p i − 1 ) = 1 + ∑ i = 1 a ( − p i − 1 + p i ) \sum_{d|n}\varphi(d) = \sum_{i=0}^{a} \varphi(p^i) = 1 + \sum_{i=1}^{a}( p^i - p^{i-1}) = 1 + \sum_{i=1}^a(-p^{i-1} + p^i) dnφ(d)=i=0aφ(pi)=1+i=1a(pipi1)=1+i=1a(pi1+pi)

显然,将求和式展开,会有一些项可以合并。
比如 a = 3 a = 3 a=3时,原式等于: 1 − p 0 + p 1 − p 1 + p 2 − p 2 + p 3 = p 3 1 - p^0 + p^1- p^1 + p^2 - p^2 + p^3 = p^3 1p0+p1p1+p2p2+p3=p3
可见:
∑ d ∣ n φ ( d ) = ∑ i = 0 a φ ( p i ) = p a = n \sum_{d|n}\varphi(d) = \sum_{i=0}^a \varphi(p^i) = p^a = n dnφ(d)=i=0aφ(pi)=pa=n

n n n含多个质因子时,即 n = p 1 a 1 p 2 a 2 . . . p k a k n = p_1^{a_1}p_2^{a_2}...p_k^{a_k} n=p1a1p2a2...pkak
利用积性函数的性质有
∑ d ∣ n φ ( d ) = ∑ i = 0 a 1 φ ( p 1 i ) ∑ i = 0 a 2 ϕ ( p 2 i ) . . . . . . ∑ i = 0 a k φ ( p k i ) \sum_{d|n}\varphi(d) = \sum_{i=0}^{a_1} \varphi(p_1^i)\sum_{i=0}^{a_2} \phi(p_2^i) ...... \sum_{i=0}^{a_k} \varphi(p_k^i) dnφ(d)=i=0a1φ(p1i)i=0a2ϕ(p2i)......i=0akφ(pki)

同上易得:
原 式 = p 1 a 1 p 2 a 2 . . . . . . p k a k = n 原式=p_1^{a_1}p_2^{a_2} ...... p_k^{a_k} = n =p1a1p2a2......pkak=n
证毕。

(5)当 n > 1 n>1 n>1,小于 n n n且与 n n n互质的数之和为 s u m = n φ ( n ) 2 sum = \frac{n\varphi(n)}{2} sum=2nφ(n)

证明:在数论求 g c d gcd gcd中,有两个非常出名的公式,基于这两个公式,出现了两种快速求 g c d gcd gcd的方法,更相减损法和辗转相除法。这两个公式是:(假设有两个正整数 a , b a,b a,b且满足 a > b a>b a>b)
g c d ( a , b ) = g c d ( a , a − b ) gcd(a,b) = gcd(a,a-b) gcd(a,b)=gcd(a,ab) g c d ( a , b ) = g c d ( b , a % b ) gcd(a,b) = gcd(b,a\%b) gcd(a,b)=gcd(b,a%b)

由第一个公式,知:
m m m n n n互质,则 n − m n-m nm也一定与 n n n互质。
这样就能将保证当 n > 2 n>2 n>2时, φ ( n ) \varphi(n) φ(n)一定为偶数,且可两两配对,每一对的和都是 n n n
s u m = n φ ( n ) 2 sum = n\frac{\varphi(n)}{2} sum=n2φ(n)
n = 2 n=2 n=2时,代入验证知,此公式依然满足。

证毕。


例题:HDU 3501
题意:求小于n且与n不互质的数之和。
思路:直接利用公式求反面,总数 - 反面数即为答案。
代码:

#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;

const int mod = 1000000007;
const int A = 1e5 + 10;
bool vis[A];
int pri[A],tot;

void init(){
    tot = 0;
    vis[0] = vis[1] = 1;
    for(int i=2 ;i<A ;i++){
        if(vis[i] == 0) pri[++tot] = i;
        for(int j=1 ;j<=tot&&pri[j]*i<A ;j++){
            vis[pri[j]*i] = 1;
            if(i%pri[j] == 0) break;
        }
    }
}

int main(){
    init();
    ll n;
    while(~scanf("%I64d",&n) && n){
        ll ans = (n*(n-1)/2)%mod;
        ll res = n,m = n;
        for(int i=1 ;i<=tot&&pri[i]*pri[i]<=n ;i++){
            if(n%pri[i] == 0){
                res = res/pri[i]*(pri[i]-1);
                while(n%pri[i] == 0) n/=pri[i];
            }
        }
        if(n!=1) res = res/n*(n-1);
        ans = ans - res*m/2;
        printf("%I64d\n",(ans%mod+mod)%mod);
    }
    return 0;
}

莫比乌斯函数 μ \mu μ

定义式:
μ ( n ) = { 1 ( n = 1 ) ( − 1 ) k ( n = p 1 p 2 . . . p k ) 0 ( e l s e ) \mu(n) = \begin{cases} 1 & (n=1)\\ (-1)^k&(n=p_1p_2...p_k)\\ 0&(else)\\ \end{cases} μ(n)=1(1)k0(n=1)(n=p1p2...pk)(else)

性质:
(1)对于任意正整数n,有:
∑ d ∣ n μ ( d ) = [ n = = 1 ] \sum_{d|n} \mu(d) = [n == 1] dnμ(d)=[n==1]

该性质在莫比乌斯反演中有着极大应用。

证明:
n = 1 n = 1 n=1时 等式显然成立。
n > 1 n>1 n>1时,令 n = p 1 a 1 p 2 a 2 p 3 a 3 . . . p k a k n = p_1^{a_1}p_2^{a_2}p_3^{a_3} ... p_k^{a_k} n=p1a1p2a2p3a3...pkak
考虑莫比乌斯函数取值的特殊性,若函数值不为 0 0 0,则d只含每个质因子的 0 0 0次或 1 1 1次项。
∑ d ∣ n μ ( d ) = C k 0 − C k 1 + C k 2 . . . + ( − 1 ) k C k k = ∑ i = 0 k ( − 1 ) i C k i \sum_{d|n}\mu(d) = C_k^0 - C_k^1 + C_k^2 ...+(-1)^kC_k^k = \sum_{i=0}^k(-1)^iC_k^i dnμ(d)=Ck0Ck1+Ck2...+(1)kCkk=i=0k(1)iCki

由二项式定理,原式等于:
∑ i = 0 k ( − 1 ) i C k i = ∑ i = 0 k C k i ( − 1 ) i ( 1 ) k − i = ( − 1 + 1 ) k = 0 \sum_{i=0}^k(-1)^iC_k^i = \sum_{i=0}^kC_k^i(-1)^i(1)^{k-i} = (-1 + 1)^k = 0 i=0k(1)iCki=i=0kCki(1)i(1)ki=(1+1)k=0

综上所述:
n = 1 n=1 n=1原式为 1 1 1
n > 1 n>1 n>1原式为 0 0 0
证毕。

(2)对于任意正整数 n n n,有:
∑ d ∣ n μ ( d ) d = φ ( n ) n \sum_{d|n}\frac{\mu(d)}{d} = \frac{\varphi(n)}{n} dndμ(d)=nφ(n)

证明:
f ( n ) f(n) f(n)满足: f ( n ) = ∑ d ∣ n φ ( d ) f(n) = \sum_{d|n}\varphi(d) f(n)=dnφ(d)

由欧拉函数的性质 ( 4 ) (4) (4) f ( n ) = n f(n) = n f(n)=n
又由莫比乌斯反演: φ ( n ) = ∑ d ∣ n μ ( d ) f ( n d ) \varphi(n) = \sum_{d|n}\mu(d)f(\frac{n}{d}) φ(n)=dnμ(d)f(dn)
推出:
φ ( n ) = ∑ d ∣ n n μ ( d ) d = n ∑ d ∣ n μ ( d ) d \varphi(n) = \sum_{d|n}n\frac{\mu(d)}{d} = n \sum_{d|n} \frac{\mu(d)}{d} φ(n)=dnndμ(d)=ndndμ(d)

等式两边同除以n,得:
φ ( n ) n = ∑ d ∣ n μ ( d ) d \frac{\varphi(n)}{n} = \sum_{d|n}\frac{\mu(d)}{d} nφ(n)=dndμ(d)
证毕。


线性筛求积性函数

欧拉函数 φ \varphi φ

考虑将所有数分成三类:
(1)质数 φ ( i ) = i − 1 \varphi(i) = i - 1 φ(i)=i1

(2)最小质因子指数为1: φ ( i ∗ p ) = φ ( i ) φ ( p ) \varphi(i*p) = \varphi(i) \varphi(p) φ(ip)=φ(i)φ(p)

(3)最小质因子指数大于1: φ ( i ∗ p ) = p ∗ φ ( i ) \varphi(i*p) = p*\varphi(i) φ(ip)=pφ(i)(可从欧拉函数的定义式出发)

代码:

void init(){
    tot = 0;phi[1] = 1;
    for(int i=2 ;i<A ;i++){
        if(!vis[i]){pri[++tot] = i;phi[i] = i-1;}
        for(int j=1 ;j<=tot&&i*pri[j]<A ;j++){
            vis[i*pri[j]] = 1;
            if(i%pri[j] == 0){
                phi[i*pri[j]] = pri[j] * phi[i];break;
            }
            phi[i*pri[j]] = phi[pri[j]] * phi[i];
        }
    }
}

莫比乌斯函数 μ \mu μ

因为线性筛每次都是用最小质因子去筛每一个数。
故也可分为三类:
(1) i i i为质数: μ [ i ] = − 1 \mu[i] = -1 μ[i]=1

(2) i i i已经包含最小质因子 p p p μ [ i ∗ p ] = 0 \mu[i*p] = 0 μ[ip]=0

(3) i i i不包含最小质因子 p p p μ [ i ∗ p ] = − μ [ i ] \mu[i*p] = -\mu[i] μ[ip]=μ[i]

代码:

void init(){
    tot = 0;mu[1] = 1;
    for(int i=2 ;i<A ;i++){
        if(!vis[i]){pri[++tot] = i;mu[i] = -1;}
        for(int j=1 ;j<=tot&&i*pri[j]<A ;j++){
            vis[i*pri[j]] = 1;
            if(i%pri[j] == 0){mu[i*pri[j]] = 0;break;}
            mu[i*pri[j]] = -mu[i];
        }
    }
}

以下为其他常见积性函数的线性筛:

约数个数函数d

仍然分三类讨论,此时我们还需要维护每一个数 i i i最小质因子的指数 c n t [ i ] cnt[i] cnt[i]
(1) i i i为质数:$d[i] = 2 $ c n t [ i ] = 1 cnt[i] = 1 cnt[i]=1

(2) i i i已经包含最小质因子 p p p
d [ i ∗ p ] = d [ i ] / ( c n t [ i ] + 1 ) ∗ ( c n t [ i ] + 2 ) d[i*p] = d[i]/(cnt[i]+1)*(cnt[i]+2) d[ip]=d[i]/(cnt[i]+1)(cnt[i]+2) (由约数个数公式易得)
c n t [ i ∗ p ] = c n t [ i ] + 1 cnt[i*p] = cnt[i] + 1 cnt[ip]=cnt[i]+1

(3) i i i不包含最小质因子 p p p
d [ i ∗ p ] = d [ i ] ∗ ( c n t [ p ] + 1 ) = d [ i ] ∗ 2 d[i*p] = d[i]*(cnt[p] + 1) = d[i]*2 d[ip]=d[i](cnt[p]+1)=d[i]2
c n t [ i ∗ p ] = 1 cnt[i*p] = 1 cnt[ip]=1

代码:

void init(){
    tot = 0;d[1] = 1;
    for(int i=2 ;i<A ;i++){
        if(!vis[i]){pri[++tot] = i;d[i] = 2;cnt[i] = 1;}
        for(int j=1 ;j<=tot&&i*pri[j]<A ;j++){
            vis[i*pri[j]] = 1;
            if(i%pri[j] == 0){
                d[i*pri[j]] = d[i]/(cnt[i]+1)*(cnt[i]+2);
                cnt[i*pri[j]] = cnt[i] + 1;
                break;
            }
            d[i*pri[j]] = d[i]<<1;
            cnt[i*pri[j]] = 1;
        }
    }
}

约数和函数 σ \sigma σ

假设一个正整数 n n n分解质因子之后为:
n = p 1 a 1 p 2 a 2 p 3 a 3 . . . p k a k n = p_1^{a_1}p_2^{a_2}p_3^{a_3} ... p_k^{a_k} n=p1a1p2a2p3a3...pkak

σ ( n ) = ∑ i = 0 a 1 p 1 i ∑ i = 0 a 2 p 2 i . . . . . ∑ i = 0 a k p k i \sigma(n) = \sum_{i=0}^{a_1}p_1^i \sum_{i=0}^{a_2}p_2^i..... \sum_{i=0}^{a_k}p_k^i σ(n)=i=0a1p1ii=0a2p2i.....i=0akpki

假设最小质因子为 p 1 p_1 p1故线性筛中每一个被筛到的数比起原来的数,差别只在于: ∑ i = 0 a 1 p 1 i \sum_{i=0}^{a_1} p_1^i i=0a1p1i

故我们可以维护两个量:
s u m [ i ] : i sum[i]:i sum[i]:i的最小质因子 p 1 p_1 p1贡献的和: ∑ i = 0 a 1 p 1 i \sum_{i=0}^{a_1} p_1^i i=0a1p1i
M x [ i ] : Mx[i]: Mx[i]: p 1 a 1 p_1^{a_1} p1a1 a 1 a_1 a1 为最小质因子的最高次数。

然后又可以把所有数分成三类:
(1) i i i为质数: σ [ i ] = i + 1 \sigma[i] = i+1 σ[i]=i+1 s u m [ i ] = i + 1 sum[i] = i+1 sum[i]=i+1 M x [ i ] = i Mx[i] = i Mx[i]=i

(2) i i i已经包含最小质因子 p p p σ [ i ∗ p ] = σ [ i ] / s u m [ i ] ∗ ( s u m [ i ] + M x [ i ] ∗ p ) \sigma[i*p] = \sigma[i]/sum[i]*(sum[i]+Mx[i]*p) σ[ip]=σ[i]/sum[i](sum[i]+Mx[i]p)
s u m [ i ∗ p ] = s u m [ i ] + M x [ i ] ∗ p sum[i*p] = sum[i] + Mx[i]*p sum[ip]=sum[i]+Mx[i]p
M x [ i ∗ p ] = M x [ i ] ∗ p Mx[i*p] = Mx[i]*p Mx[ip]=Mx[i]p

(3) i i i不包含最小质因子 p p p σ [ i ∗ p ] = σ [ i ] ∗ σ [ p ] = σ [ i ] ∗ ( p + 1 ) \sigma[i*p] = \sigma[i]*\sigma[p]= \sigma[i]*(p+1) σ[ip]=σ[i]σ[p]=σ[i](p+1)
s u m [ i ∗ p ] = p + 1 sum[i*p] = p+1 sum[ip]=p+1
M x [ i ∗ p ] = p Mx[i*p] = p Mx[ip]=p


代码:

void init(){
    tot = 0;Sigma[1] = 1;
    for(int i=2 ;i<A ;i++){
        if(!vis[i]){
            pri[++tot] = i;
            Sigma[i] = 1 + i;
            sum[i] = 1 + i;
            Mx[i] = i;
        }
        for(int j=1 ;j<=tot&&i*pri[j]<A ;j++){
            vis[i*pri[j]] = 1;
            if(i%pri[j] == 0){
                Sigma[i*pri[j]] = Sigma[i]/sum[i]*(sum[i] + Mx[i]*pri[j]);
                sum[i*pri[j]] = sum[i] + Mx[i]*pri[j];
                Mx[i*pri[j]] = Mx[i]*pri[j];
                break;
            }
            Sigma[i*pri[j]] = Sigma[i]*(pri[j] + 1);
            sum[i*pri[j]] = pri[j] + 1;
            Mx[i*pri[j]] = pri[j];
        }
    }
}

你可能感兴趣的:(积性函数的性质及证明 + 线性筛)