莫比乌斯反演与积性函数部分(转载)

https://blog.csdn.net/consciousman/article/details/77888386

https://blog.csdn.net/skywalkert/article/details/50500009(偏理论)

莫比乌斯与积性函数

之前做过不少的数论题,关于莫比乌斯与积性函数的数论题挺多的。。。特地过来总结一下。。当作自己的一个回顾了-_-

先安利一下神犇tls的博客和神犇PoPoQQQ的pdf !
膜拜tls…
跪popoqqq…
还有IOI金牌神犇任之州的集训队论文,都是好文啊!

需要先知道线性筛这个东西。。
orz…
线性筛的思想是每个合数都只会被它最小的质因数筛去,通过线性筛,我们可以O(n)得到1到n内一些数论函数的值,比如说欧拉函数、莫比乌斯函数、因子个数等等。。。

本文的除法均为整除,除非特别指出。
[expresion]为bool表达式,值为0或1,当且仅当expresion为真时为1,否则为0。
(i,j)表示gcd(i,j)。

莫比乌斯反演

莫比乌斯函数

首先定义莫比乌斯函数

u(i)=⎧⎩⎨1,(−1)k,0,if n = 1if n=p1∗p2∗...∗pk 其它u(i)={1,if n = 1(−1)k,if n=p1∗p2∗...∗pk 0,其它


根据上面的定义,n大于1时且n是平方因子数时莫比乌斯函数值为0,否则从n的唯一分解定理中根据素数的个数取奇偶即可。

 

莫比乌斯函数的性质:

1) ∑d|nu(d)=⎧⎩⎨1,0,if n = 1其它∑d|nu(d)={1,if n = 10,其它
有了上述这个式子,我们就可以直接简单地以O(nlogn)筛出1到n内所有数的莫比乌斯函数值了~
至此我们已经有两种办法求1到n内所有数的欧拉函数值了。

//O(n)
bool vis[N];
int primes[N], miu[N];
int init(int n) {
    int tot = 0;
    miu[1] = 1;
    for (int i = 2; i <= n; i++) {
        if (!vis[i]) {
            primes[tot++] = i;
            miu[i] = -1;
        }
        for (int j = 0; j < tot; j++) {
            int k = i * primes[j];
            if (k > n)break;
            vis[k] = true;
            if (i % primes[j])  miu[k] = -miu[i];
            else break;
        }
    }
}
//O(nlogn)
void init(int n) {
    miu[1] = 1;
    int t = n >> 1;
    for (int i = 1; i <= t; i++) if (miu[i]) {
        for (int j = i << 1; j <= n; j += i) miu[j] -= miu[i];
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

2) ∑d|nu(d)d=φ(n)n∑d|nu(d)d=φ(n)n

莫比乌斯函数除了可以用在莫比乌斯反演中之外,还可以用来进行容斥。
举一个常见的例子,求取1到n这个区间内有多少个数与x互质,一般的做法是直接进行容斥,但是我们可以发现容斥的系数刚好是莫比乌斯函数,即ans = ∑d|xu(d)∗nd∑d|xu(d)∗nd,其实这两者从本质考虑是完全等价的。

莫比乌斯反演

莫比乌斯反演是一个这样的式子:
定义F(n)=∑d|nf(n)F(n)=∑d|nf(n),那么可以得到f(n)=∑d|nu(nd)F(d)f(n)=∑d|nu(nd)F(d)
莫比乌斯反演还有一种更常见的形式:F(n)=∑n|df(d)F(n)=∑n|df(d), 那么有f(n)=∑n|du(dn)F(d)f(n)=∑n|du(dn)F(d)。
一般应用的都是上述的第二种形式,证明可以通过归纳得出,也可以直接通过式子变换得出,还可以由狄利克雷卷积证明。
f(n)=∑d|nu(nd)F(d)=∑d|nu(nd)∑x|df(x)=∑d|nf(d)∑x|ndu(x)=f(n)f(n)=∑d|nu(nd)F(d)=∑d|nu(nd)∑x|df(x)=∑d|nf(d)∑x|ndu(x)=f(n)
上述的证明中给出了一种常见的和式变换技巧:交换求和顺序。通过交换求和顺序,我们往往可以将某些和式化简或者更容易求出该和式,后面公式的化简将多次用到。

莫比乌斯反演还有一个推广式,如下:
这里写图片描述

积性函数

积性函数定义

设f(x)f(x)为一个数论函数,如果对于任意正整数a、b满足(a,b)=1(a,b)=1,有f(ab)=f(a)∗f(b)f(ab)=f(a)∗f(b)的话,我们称f(n)f(n)为积性函数;如果对于任意正整数啊a、b有f(ab)=f(a)∗f(b)f(ab)=f(a)∗f(b)的话,我们称f(n)f(n)为完全积性函数。
常见的积性函数有:
因子个数函数d(n)d(n),因子和函数σ(n)σ(n),二元函数gcd(a,b)gcd(a,b),欧拉函数φ(n)φ(n),莫比乌斯函数u(n)u(n)。
完全积性函数有:
元函数e(n)=[n==1]e(n)=[n==1],恒等函数I(n)=1I(n)=1,单位函数id(n)=nid(n)=n。

积性函数应用

我们来看看积性函数的应用:
如果f(x)f(x)为积性函数且n=∑ti=1peiin=∑i=1tpiei,那么可以得到f(n)=∏ti=1f(peii)f(n)=∏i=1tf(piei),如果f(x)为完全积性函数,那么我们还可以进一步得到f(n)=∏ti=1f(pi)eif(n)=∏i=1tf(pi)ei。
举个简单的例子:因子个数d(n)=∏ti=1d(peii)=∏ti=1(ei+1)d(n)=∏i=1td(piei)=∏i=1t(ei+1),因子和函数σ(n)=∏ti=1σ(peii)=∏ti=1piei+1−1pi−1σ(n)=∏i=1tσ(piei)=∏i=1tpiei+1−1pi−1。
积性函数还可以用来进行线性筛从而得到很多数论函数的值~
比如下面的欧拉函数:
可以知道当i%p==0i%p==0时,φ(i∗p)=φ(i)∗pφ(i∗p)=φ(i)∗p,而当i%p!=0i%p!=0时,有

φ(i∗p)=φ(i)∗φ(p)=φ(i)∗(p−1)φ(i∗p)=φ(i)∗φ(p)=φ(i)∗(p−1)

 

const int N = 1e6 + 5;
bool vis[N];
int phi[N], p[N], cnt = 0;
void seive() {
    cnt = 0;
    phi[1] = 1;
    for (int i = 2; i < N; i++) {
        if (!vis[i]) p[cnt++] = i, phi[i] = i - 1;
        for (int j = 0; j < cnt; j++) {
            int s = i * p[j];
            if (s > N) break;
            vis[s] = 1;
            if (i % p[j] == 0) {
                phi[s] = p[j] * phi[i];
                break;
            }
            phi[s] = (p[j] - 1) * phi[i];
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

积性函数前缀和

积性函数的和也是积性函数,积性函数前缀和是一个常见的问题,常常需要低于线性时间内解决。

狄利克雷卷积

狄利克雷卷积是解决积性函数前缀和问题的一个重要工具。

定义

对两个算术函数f, g,定义其Dirichlet卷积为新函数f * g,满足(f∗g)(n)=∑d|nf(d)g(nd)(f∗g)(n)=∑d|nf(d)g(nd)。
狄利克雷卷积满足以下定律:
这里写图片描述
若f,g均为积性函数,则f*g也是积性函数。
我们可以O(nlogn)预处理两个函数的Dirichlet卷积。

LL f[N], g[N], h[N];
void calc(int n) {
    for (int i = 1; i * i <= n; i++) {
        h[i * i] += f[i] * g[i];
        for (int j = i + 1; i * j <= n; j++) h[i * j] += f[i] * g[j] + f[j] * g[i];
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

举例

很多数论函数都可以用狄利克雷卷积来表示:
①约数个数函数d(n)=(I∗I)(n)d(n)=(I∗I)(n);
②约数和函数d(n)=(I∗id)(n)d(n)=(I∗id)(n);
③∑d|nu(d)=[n==1]∑d|nu(d)=[n==1],得到I∗u=eI∗u=e。
④∑d|nφ(d)=n∑d|nφ(d)=n,得到I∗φ=idI∗φ=id。

现在我们可以通过狄利克雷卷积来证明莫比乌斯反演了:
如果F(n)=∑d|nf(n)F(n)=∑d|nf(n),那么F = I*f,那么可以知道F*u = I*f*u=f*(I*u)=f*e=f,所以f(n)=∑d|nu(nd)F(d)f(n)=∑d|nu(nd)F(d)。

应用

设f(n)为一个数论函数,需要计算S(n)=∑ni=1f(i)S(n)=∑i=1nf(i),通常n>=1e9。
要解决上述问题,我们可以构造一个S(n)S(n)关于S(ni)S(ni)的递推式。
找到一个合适的数论函数g(n),

∑i=1n∑d|if(d)g(id)=∑i=1ng(i)∑j=1nif(j)=∑i=1ng(i)S(ni)∑i=1n∑d|if(d)g(id)=∑i=1ng(i)∑j=1nif(j)=∑i=1ng(i)S(ni)


这样,可以知道g(1)S(n)=∑ni=1(f∗g)(i)−∑ni=2g(i)∗S(ni)g(1)S(n)=∑i=1n(f∗g)(i)−∑i=2ng(i)∗S(ni)。
构造的卷积函数必须容易求得前缀和,这样我们可以记忆化地计算S(n),因为nini是分段的,可以计算出复杂度为O(n34)O(n34),只要我们预处理S函数前2323的值,复杂度就可以达到O(n23)O(n23)
上述的办法就是传说中的杜教筛了~
如果找不到适合的函数g(n),那么可以采用一种复杂度为O(n34logn)O(n34logn)的办法来实现求和,详见任之州的论文。

 

下面给出

莫比乌斯与积性函数

之前做过不少的数论题,关于莫比乌斯与积性函数的数论题挺多的。。。特地过来总结一下。。当作自己的一个回顾了-_-

先安利一下神犇tls的博客和神犇PoPoQQQ的pdf !
膜拜tls…
跪popoqqq…
还有IOI金牌神犇任之州的集训队论文,都是好文啊!

需要先知道线性筛这个东西。。
orz…
线性筛的思想是每个合数都只会被它最小的质因数筛去,通过线性筛,我们可以O(n)得到1到n内一些数论函数的值,比如说欧拉函数、莫比乌斯函数、因子个数等等。。。

本文的除法均为整除,除非特别指出。
[expresion]为bool表达式,值为0或1,当且仅当expresion为真时为1,否则为0。
(i,j)表示gcd(i,j)。

莫比乌斯反演

莫比乌斯函数

首先定义莫比乌斯函数

u(i)=⎧⎩⎨1,(−1)k,0,if n = 1if n=p1∗p2∗...∗pk 其它u(i)={1,if n = 1(−1)k,if n=p1∗p2∗...∗pk 0,其它


根据上面的定义,n大于1时且n是平方因子数时莫比乌斯函数值为0,否则从n的唯一分解定理中根据素数的个数取奇偶即可。

 

莫比乌斯函数的性质:

1) ∑d|nu(d)=⎧⎩⎨1,0,if n = 1其它∑d|nu(d)={1,if n = 10,其它
有了上述这个式子,我们就可以直接简单地以O(nlogn)筛出1到n内所有数的莫比乌斯函数值了~
至此我们已经有两种办法求1到n内所有数的欧拉函数值了。

//O(n)
bool vis[N];
int primes[N], miu[N];
int init(int n) {
    int tot = 0;
    miu[1] = 1;
    for (int i = 2; i <= n; i++) {
        if (!vis[i]) {
            primes[tot++] = i;
            miu[i] = -1;
        }
        for (int j = 0; j < tot; j++) {
            int k = i * primes[j];
            if (k > n)break;
            vis[k] = true;
            if (i % primes[j])  miu[k] = -miu[i];
            else break;
        }
    }
}
//O(nlogn)
void init(int n) {
    miu[1] = 1;
    int t = n >> 1;
    for (int i = 1; i <= t; i++) if (miu[i]) {
        for (int j = i << 1; j <= n; j += i) miu[j] -= miu[i];
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

2) ∑d|nu(d)d=φ(n)n∑d|nu(d)d=φ(n)n

莫比乌斯函数除了可以用在莫比乌斯反演中之外,还可以用来进行容斥。
举一个常见的例子,求取1到n这个区间内有多少个数与x互质,一般的做法是直接进行容斥,但是我们可以发现容斥的系数刚好是莫比乌斯函数,即ans = ∑d|xu(d)∗nd∑d|xu(d)∗nd,其实这两者从本质考虑是完全等价的。

莫比乌斯反演

莫比乌斯反演是一个这样的式子:
定义F(n)=∑d|nf(n)F(n)=∑d|nf(n),那么可以得到f(n)=∑d|nu(nd)F(d)f(n)=∑d|nu(nd)F(d)
莫比乌斯反演还有一种更常见的形式:F(n)=∑n|df(d)F(n)=∑n|df(d), 那么有f(n)=∑n|du(dn)F(d)f(n)=∑n|du(dn)F(d)。
一般应用的都是上述的第二种形式,证明可以通过归纳得出,也可以直接通过式子变换得出,还可以由狄利克雷卷积证明。
f(n)=∑d|nu(nd)F(d)=∑d|nu(nd)∑x|df(x)=∑d|nf(d)∑x|ndu(x)=f(n)f(n)=∑d|nu(nd)F(d)=∑d|nu(nd)∑x|df(x)=∑d|nf(d)∑x|ndu(x)=f(n)
上述的证明中给出了一种常见的和式变换技巧:交换求和顺序。通过交换求和顺序,我们往往可以将某些和式化简或者更容易求出该和式,后面公式的化简将多次用到。

莫比乌斯反演还有一个推广式,如下:
这里写图片描述

积性函数

积性函数定义

设f(x)f(x)为一个数论函数,如果对于任意正整数a、b满足(a,b)=1(a,b)=1,有f(ab)=f(a)∗f(b)f(ab)=f(a)∗f(b)的话,我们称f(n)f(n)为积性函数;如果对于任意正整数啊a、b有f(ab)=f(a)∗f(b)f(ab)=f(a)∗f(b)的话,我们称f(n)f(n)为完全积性函数。
常见的积性函数有:
因子个数函数d(n)d(n),因子和函数σ(n)σ(n),二元函数gcd(a,b)gcd(a,b),欧拉函数φ(n)φ(n),莫比乌斯函数u(n)u(n)。
完全积性函数有:
元函数e(n)=[n==1]e(n)=[n==1],恒等函数I(n)=1I(n)=1,单位函数id(n)=nid(n)=n。

积性函数应用

我们来看看积性函数的应用:
如果f(x)f(x)为积性函数且n=∑ti=1peiin=∑i=1tpiei,那么可以得到f(n)=∏ti=1f(peii)f(n)=∏i=1tf(piei),如果f(x)为完全积性函数,那么我们还可以进一步得到f(n)=∏ti=1f(pi)eif(n)=∏i=1tf(pi)ei。
举个简单的例子:因子个数d(n)=∏ti=1d(peii)=∏ti=1(ei+1)d(n)=∏i=1td(piei)=∏i=1t(ei+1),因子和函数σ(n)=∏ti=1σ(peii)=∏ti=1piei+1−1pi−1σ(n)=∏i=1tσ(piei)=∏i=1tpiei+1−1pi−1。
积性函数还可以用来进行线性筛从而得到很多数论函数的值~
比如下面的欧拉函数:
可以知道当i%p==0i%p==0时,φ(i∗p)=φ(i)∗pφ(i∗p)=φ(i)∗p,而当i%p!=0i%p!=0时,有

φ(i∗p)=φ(i)∗φ(p)=φ(i)∗(p−1)φ(i∗p)=φ(i)∗φ(p)=φ(i)∗(p−1)

 

const int N = 1e6 + 5;
bool vis[N];
int phi[N], p[N], cnt = 0;
void seive() {
    cnt = 0;
    phi[1] = 1;
    for (int i = 2; i < N; i++) {
        if (!vis[i]) p[cnt++] = i, phi[i] = i - 1;
        for (int j = 0; j < cnt; j++) {
            int s = i * p[j];
            if (s > N) break;
            vis[s] = 1;
            if (i % p[j] == 0) {
                phi[s] = p[j] * phi[i];
                break;
            }
            phi[s] = (p[j] - 1) * phi[i];
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

积性函数前缀和

积性函数的和也是积性函数,积性函数前缀和是一个常见的问题,常常需要低于线性时间内解决。

狄利克雷卷积

狄利克雷卷积是解决积性函数前缀和问题的一个重要工具。

定义

对两个算术函数f, g,定义其Dirichlet卷积为新函数f * g,满足(f∗g)(n)=∑d|nf(d)g(nd)(f∗g)(n)=∑d|nf(d)g(nd)。
狄利克雷卷积满足以下定律:
这里写图片描述
若f,g均为积性函数,则f*g也是积性函数。
我们可以O(nlogn)预处理两个函数的Dirichlet卷积。

LL f[N], g[N], h[N];
void calc(int n) {
    for (int i = 1; i * i <= n; i++) {
        h[i * i] += f[i] * g[i];
        for (int j = i + 1; i * j <= n; j++) h[i * j] += f[i] * g[j] + f[j] * g[i];
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

举例

很多数论函数都可以用狄利克雷卷积来表示:
①约数个数函数d(n)=(I∗I)(n)d(n)=(I∗I)(n);
②约数和函数d(n)=(I∗id)(n)d(n)=(I∗id)(n);
③∑d|nu(d)=[n==1]∑d|nu(d)=[n==1],得到I∗u=eI∗u=e。
④∑d|nφ(d)=n∑d|nφ(d)=n,得到I∗φ=idI∗φ=id。

现在我们可以通过狄利克雷卷积来证明莫比乌斯反演了:
如果F(n)=∑d|nf(n)F(n)=∑d|nf(n),那么F = I*f,那么可以知道F*u = I*f*u=f*(I*u)=f*e=f,所以f(n)=∑d|nu(nd)F(d)f(n)=∑d|nu(nd)F(d)。

应用

设f(n)为一个数论函数,需要计算S(n)=∑ni=1f(i)S(n)=∑i=1nf(i),通常n>=1e9。
要解决上述问题,我们可以构造一个S(n)S(n)关于S(ni)S(ni)的递推式。
找到一个合适的数论函数g(n),

∑i=1n∑d|if(d)g(id)=∑i=1ng(i)∑j=1nif(j)=∑i=1ng(i)S(ni)∑i=1n∑d|if(d)g(id)=∑i=1ng(i)∑j=1nif(j)=∑i=1ng(i)S(ni)


这样,可以知道g(1)S(n)=∑ni=1(f∗g)(i)−∑ni=2g(i)∗S(ni)g(1)S(n)=∑i=1n(f∗g)(i)−∑i=2ng(i)∗S(ni)。
构造的卷积函数必须容易求得前缀和,这样我们可以记忆化地计算S(n),因为nini是分段的,可以计算出复杂度为O(n34)O(n34),只要我们预处理S函数前2323的值,复杂度就可以达到O(n23)O(n23)
上述的办法就是传说中的杜教筛了~
如果找不到适合的函数g(n),那么可以采用一种复杂度为O(n34logn)O(n34logn)的办法来实现求和,详见任之州的论文。

 

下面给出求积性函数前缀和时常用到的一些公式和结论:
①∑d|nu(d)=[ns==1]∑d|nu(d)=[n==1]。
②∑d|nφ(d)=n∑d|nφ(d)=n。
③∑ni=1i∗[(i,n)==1]=n∗φ(n)+[n==1]2∑i=1ni∗[(i,n)==1]=n∗φ(n)+[n==1]2。
④d(n2)=∑d|n2w(d)=∑d|n∑i|du2(i)d(n2)=∑d|n2w(d)=∑d|n∑i|du2(i),w(d)表示d的不同质因子的个数。
⑤d(n∗m)=∑i|n∑j|m[(i,j)==1]。d(n∗m)=∑i|n∑j|m[(i,j)==1]。

∑i=1n[(i,n)==1]∗(i−1,n)=∑d|n∑i=1n[(i,n)==1]∗[d|(i−1)]=∑d|nφ(d)∗φ(n)φ(d)=d(n)∗φ(n)。∑i=1n[(i,n)==1]∗(i−1,n)=∑d|n∑i=1n[(i,n)==1]∗[d|(i−1)]=∑d|nφ(d)∗φ(n)φ(d)=d(n)∗φ(n)。


⑦d|i∗j等价于d(i,d)|jd|i∗j等价于d(i,d)|j
上面的几个东西有些是很显然的,但是还是写出来放在一起好了,至于第六个本人能力过弱不知如何证明。。。

求积性函数前缀和时常用到的一些公式和结论:
①∑d|nu(d)=[n==1]∑d|nu(d)=[n==1]。
②∑d|nφ(d)=n∑d|nφ(d)=n。
③∑ni=1i∗[(i,n)==1]=n∗φ(n)+[n==1]2∑i=1ni∗[(i,n)==1]=n∗φ(n)+[n==1]2。
④d(n2)=∑d|n2w(d)=∑d|n∑i|du2(i)d(n2)=∑d|n2w(d)=∑d|n∑i|du2(i),w(d)表示d的不同质因子的个数。
⑤d(n∗m)=∑i|n∑j|m[(i,j)==1]。d(n∗m)=∑i|n∑j|m[(i,j)==1]。

∑i=1n[(i,n)==1]∗(i−1,n)=∑d|n∑i=1n[(i,n)==1]∗[d|(i−1)]=∑d|nφ(d)∗φ(n)φ(d)=d(n)∗φ(n)。∑i=1n[(i,n)==1]∗(i−1,n)=∑d|n∑i=1n[(i,n)==1]∗[d|(i−1)]=∑d|nφ(d)∗φ(n)φ(d)=d(n)∗φ(n)。


⑦d|i∗j等价于d(i,d)|jd|i∗j等价于d(i,d)|j
上面的几个东西有些是很显然的,但是还是写出来放在一起好了,至于第六个本人能力过弱不知如何证明。。。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值