学习笔记--数论--莫比乌斯反演初认识

  • 前言

    本文只是用比较通俗的例子让大家了解一下什么是莫比乌斯反演,其中说明
    (明明都是瞎猜)可能有纰漏。本人也是个蒟蒻,未能给出珂学证明,还望多多指教。

  • 理论基础

    1. “|”符号表示整除,
      a|b 表示b被a整除,也就是b有a这个因数,b=ka (k∈N)。
    2. “∑ ”求和符号
  • 是什么

    请先看这个例子:

    假设有两个函数F(n),f(d),且d∈{x| x|n(即n被d整除)}
    并有以下关系:F(n)等于所有f(d)之和。

    比如:6能被1,2,3,6整除,所以F(6)=f(1)+f(2)+f(3)+f(6)
    用一个公示表示就是:

    由此可得到:

    F(1)=f(1)

    F(2)=f(1)+f(2)

    F(3)=f(1)+ f(3)

    F(4)=f(1)+f(2)+f(4)

    F(5)=f(1)+f(5)

    F(6)=f(1)+f(2)+f(3)+f(6)

    F(7)=f(1)+f(7)

    稍微变形得到:

    f(1)=F(1)

    f(2)=F(2)-f(1)=F(2)-F(1)

    f(3)=F(3)-F(1)

    f(4)=F(4)-f(2)-f(1)=F(4)-F(2)

    f(5)=F(5)-F(1)

    f(6)=F(6)-F(3)-F(2)+F(1)

    f(7)=F(7)-F(1)

    f(8)=F(8)-F(4)

    emmmmm这样如果我们知道各个F(n)的值我们肯定能算出各个f(d)的值,只要打表推就可以了,但仔细观察一下,有没有什么规律呢?

    好像每一个f(n)都由它所有的因子d∈{x| x|n(即n被d整除)}的F(d)乘上一个0或1或-1的系数再相加得到,我们就把这个系数也看成是d的一个函数μ(d),称作莫比乌斯函数

    那莫比乌斯函数的值我们怎么知道呢?有没有一个通项公式?

    我们就从最特殊的f(6)着手:
    f(6)=F(6)-F(3)-F(2)+F(1)
    我们不妨这样看:

    f(6)=1×F(6/1)+(-1)×F(6/2)+(-1)×F(6/3)+1×F(6/6)

    此时好像有点端倪了,我们可以将F()中每个分母看作d,且把1看做特殊情况:μ(1)=1,易看出μ(2)=-1,μ(3)=-1,μ(6)=1.

    这时相信不少大佬已看出μ(d)的值与d本身互异质因子个数有关。
    2只有一个质因子2,3只有一个质因子3,而6有两个质因子2和3。

    假设一正整数d的互异质因子个数为k,则μ(d)=(-1)^k。
    特殊的μ(1)=1.

    那有些μ(d)却等于0怎么解释呢???
    比如:f(8)= F(8)-F(4),

    根据上文的推测,我们知道,f(8)=μ(1)×F(8/1)+μ(2)×F(8/2)+μ(4)×F(8/4)+μ(8)×F(8/8)

    再看看上文我们已有的结论,正整数d的互异质因子个数这就要求d必须能为k个互异且互质的数的乘积。但是4=2×2不满足互异,8=2×4不满足互质。

    所以我们就猜想除1外不能由几个互质且互异的正整数相乘得到的数d的莫比乌斯函数值为0,例:μ(4)=0,μ(8)=0。

    下面总结一下:

    • μ(d)函数是莫比乌斯函数,如果d=1,μ(d)=1

    • 如果d为互异质数p1,p2…pk的乘积(若d本身是个质数就看是它本身一个的乘积),则μ(d)=(−1)^k

    • 否则,μ(d)=0

    然而,我们现在只是会求莫比乌斯函数值,什么是莫比乌斯反演呢?

    其实就是下面两个定理:

    • 式1(约数关系):若

    • 式二(倍数关系):若


    式1在开头已经说过,式2也类似,还请大家拿出草稿纸多演算一下,才能领悟。

  • 相关(不会证的)性质

    好吧我是从百科上截来的,不过我还找到了其他几个(全都不会证

    • 对于大于1的正整数n

    • 对于任意正整数n

    φ()就是欧拉函数,若不清楚的可以看我的这篇博客:
    我又打广告了

  • 应用

    线性方法求莫比乌斯函数值表

    和欧式筛法很像,建议先了解欧式筛法原理,其他详见代码注释

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int maxn=19260817;
int n;
int prime[maxn];//记录素数 
int mob[maxn];//记录莫比乌斯函数值 
bool vis[maxn];
int cnt=0;//记录素数个数 
void make_mob(int m)
{
	memset(vis,0,sizeof(vis));
	mob[1]=1;//特殊 
	for(int i=2;i<=m;i++)
	{
		if(!vis[i]){
			prime[++cnt]=i;
			mob[i]=-1;//素数的μ()为-1,
			//只有其本身一个互异互质因子 
		}
		for(int j=1;j<=cnt&&i*prime[j]<=m;j++)
		{
			vis[i*prime[j]]=1;//筛素数,不必多讲
			if(i%prime[j]==0){
				mob[i*prime[j]]=0;break; 
		    //设x=i*prime[j]很明显它的两个因子i与prime[j]不互质 
		    //break;大家可以先去看看欧式筛素数原理理解这句话 
			}
			mob[i*prime[j]]=-mob[i];
		//不难理解,i*prime[j]比i多了一个因子 
		}
	}
}
int main()
{
	cin>>n;
	make_mob(n);
	for(register int i=1;i<=n;i++)
	{
		cout<<mob[i]<<' ';
		if(i%10==0)putchar('\n');
	}
	return 0;
} 
posted @ 2018-02-24 17:30  Rye_Catcher  阅读(342)  评论(0编辑  收藏  举报