码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2018-02-24 19:22:03      阅读:169      评论:0      收藏:0      [点我收藏+]

标签:了解   莫比乌斯反演   cin   根据   putc   打广告   不难   utc   ++   

  • 前言

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

  • 理论基础

  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;
} 

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

标签:了解   莫比乌斯反演   cin   根据   putc   打广告   不难   utc   ++   

原文地址:https://www.cnblogs.com/Rye-Catcher/p/8467085.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!