『笔记』莫比乌斯反演

写在前面

该来的总会来,终究逃不过圈套。。

爱数学!但是对这种个人认为极其复杂的数学有种莫名的恐惧。。

前置芝士

反演

什么是反演?

参照学长 LB 的 「笔记」反演

积性函数

定义域为正整数的算术函数 (f(x)) 满足

[left{ egin{array}{l} f(n)=1 & n=1 \ f(pq)=f(p) cdot f(q) & p perp q end{array} ight. ]

一些常见的积性函数

  • 欧拉函数 (varphi(n) = sum limits_{i=1}^n [gcd(i,n)=1])

  • 莫比乌斯函数 (mu(n))

  • 最大公约数 (gcd(n,k))

完全积性函数

定义域为正整数的算术函数 (f(x)) 满足

[left{ egin{array}{l} f(n)=1 & n=1 \ f(ad)=f(a) cdot f(b) & a,b ext{任意} end{array} ight. ]

常见完全积性函数

  • 恒等函数 (I(n)=1)

  • 元函数 (epsilon(n)=[n=1])

  • 单位函数 (id(n)=n)

狄利克雷卷积(Dirichiet)

对于两算术函数 (f,g) ,定义 ((f * g)(n )=sum_{d mid n} f(d) gleft(frac{n}{d} ight)) ,其中 (n) 常常省略不写。

运算律

交换律

[f*g=g*f ]

结合律

[(f*g)*h=f*(g*h) ]

分配律

[f*(g+h)=f*g+f*h ]

应用

理论 1

[mu * I =epsilon ]

其中

[egin{aligned} &I(n)=1,\ &epsilon(n)= left{ egin{array}{l} 1 & n=1 \ 0 & n eq 1 end{array} ight. end{aligned} ]

则有

[egin{aligned} epsilon(n) &= sum limits_{d mid n} mu(d) cdot I(cfrac{n}{d})\ &=sum limits_{d mid n} mu(d) end{aligned} ]

理论 2

[varphi * I =id ]

其中 (id(n)=n)

则有

[egin{aligned} id(n) &= sum limits_{d mid n} varphi(d) cdot I(cfrac{n}{d}) \ &= sum limits_{d mid n} varphi(d) \ &= n end{aligned} ]

任何数的 (varphi) 之和都是它本身

理论 3

[mu * id =varphi ]

证明:

[egin{aligned} mu * id &= mu * I * varphi\ &= epsilon * varphi end{aligned} ]

其中

[egin{aligned} (epsilon* varphi) (n) &= sum limits_{d mid n} epsilon(d) cdot varphi(cfrac{n}{d})\ &= varphi(n) end{aligned} ]

所以 (mu * id = varphi)

注意:(epsilon) 可看作数论函数中的 (1)

莫比乌斯函数

这里详细说明一下上文提到的 (mu) ,即莫比乌斯函数

定义

莫比乌斯函数定义为

[mu(n)= left{ egin{array}{ll} 1 & n=1 \ 0 & n ext { 含有平方因子 } \ (-1)^{k} & k ext { 为 } n ext { 的本质不同质因子个数 } end{array} ight. ]

性质

莫比乌斯函数是积性函数,具有一下性质

[sum_{d mid n} mu(d)=[n=1] ]

证明

(n=prod limits_{i=1}^{k} p_{i}^{c_{i}}, n^{prime}=prod limits_{i=1}^{k} p_{i})

莫比乌斯函数定义

[sum limits_{d mid n} mu(d)=sum limits_{d mid n^{prime}} mu(d) ]

(n^prime) 的某因子 (d) ,有 (mu(d)=(-1)^prime) ,则它由 (i) 个本质不同的质因子组成。

由于质因子总数为 (k),满足上式的因子数为 (C_k^i)

对于原式,可转化为枚举 (mu(d)) 的值

[sum limits_{d mid n^{prime}} mu(d)=sum limits_{i=0}^{k} C_{k}^{i} imes(-1)^{i}=sum_{i=0}^{k} C_{k}^{i} imes(-1)^{i} imes 1^{k-i} ]

根据二项式定理,上式可化为

[[1+(-1)]^k ]

显然当 (k=0) ,即 (n=0) 时为 (1) ,否则为 (0)

线性筛求莫比乌斯函数

(mu) 为积性函数,因此可以线性筛求莫比乌斯函数。

/*
线性筛求莫比乌斯函数

By Luckyblock

有删改。
*/
int pnum, mu[_], p[_];
bool vis[_];

void Euler(int lim_)
{
    vis[1] = true;
    mu[1] = 1ll;
    for (int i = 2; i <= lim_; ++i)
    {
        if (!vis[i])
        {
            p[++pnum] = i;
            mu[i] = -1;
        }
        for (int j = 1; j <= pnum && i * p[j] <= lim_; ++j)
        {
            vis[i * p[j]] = true;
            if (!(i % p[j]))
            { //勿忘平方因子
                mu[i * p[j]] = 0;
                break;
            }
            mu[i * p[j]] = -mu[i];
        }
    }
}

莫比乌斯反演

定义

(f(n),g(n)) 两个数论函数,

[g(n)=sum limits_{dmid n} f(d) ]

则有

[egin{aligned} f(n) &= (mu * f)(n) \ &= sum limits_{d mid n}mu(d) f(cfrac{n}{d}) end{aligned} ]

证明

利用狄利克雷卷积卷积,原问题可化为

已知 (f = g * I) ,证明 (g= f * mu)

显然有

[egin{aligned} f * mu &= g * I * mu \ &Longrightarrow f * mu \ &= g * e \ &= g end{aligned} ]

证毕。

应用

这里有一个套路,一般涉及到莫比乌斯反演的题目都可以按照这个思路来。

zhx 亲授/kel

(sum limits_{i=1}^n sum limits_{j=1}^m gcd(i,j)) 的值。

“反正这题数据范围暴力肯定过不了,其他无所谓。——zhx

显然,直接暴力枚举 (O(nmlog))肯定过不了。。

能否在 (O(n)) 的时间内求解呢?

这里可以用一个非常奇妙的思想——求和变形

  1. 增加枚举变量

    (id = varphi * I)

    [egin{align} & sum limits_{i=1}^n sum limits_{j=1}^m gcd(i,j) \ =& sum limits_{i=1}^n sum limits_{j=1}^m id[ gcd(i,j)] \ =& sum limits_{i=1}^n sum limits_{j=1}^m sum limits_{d mid gcd(i,j)} varphi(d) * I \ =& sum limits_{i=1}^n sum limits_{j=1}^m sum limits_{d mid gcd(i,j)} varphi(d) end{align} ]

  2. 交换枚举顺序

    [egin{align} &sum limits_{i=1}^n sum limits_{j=1}^m sum limits_{d mid gcd(i,j)} varphi(d) ag{4}\ &=sum limits_{d=1}^n sum limits_{i=1}^{leftlfloorfrac{n}{d} ight floor} sum limits_{j=1}^{leftlfloorfrac{m}{d} ight floor} varphi(d) ag{5} end{align} ]

  3. 删除无用变量

    [egin{align} & sum limits_{d=1}^n sum limits_{i=1}^{leftlfloorfrac{n}{d} ight floor} sum limits_{j=1}^{leftlfloorfrac{m}{d} ight floor} varphi(d) ag{5} \ =& sum limits_{d=1}^n leftlfloorcfrac{n}{d} ight floor leftlfloorcfrac{m}{d} ight floor varphi(d) ag{6} end{align} ]

然后就可以直接枚举 (d=1 sim n) 求解答案。

时间复杂度 (O(n))

P2398 GCD SUM

/*

Name: P2398 GCD SUM

Solution: 
   

By Frather_

*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#define int long long
#define InF 0x3f3f3f3f
#define kMax 10e5
#define kMin -10e5
#define kMod 998244353
using namespace std;
/*==================================================快读*/
inline int read()
{
    int X = 0, F = 1;
    char CH = getchar();
    while (CH < '0' || CH > '9')
    {
        if (CH == '-')
            F = -1;
        CH = getchar();
    }
    while (CH >= '0' && CH <= '9')
    {
        X = (X << 3) + (X << 1) + (CH ^ 48);
        CH = getchar();
    }
    return X * F;
}
/*===============================================定义变量*/
int n;

const int _ = 1000010;

int prime[_], v[_], phi[_], cnt;

int res[_];

int ans;
/*=============================================自定义函数*/
void eular(int n) //线性筛筛欧拉函数
{
    memset(v, 0, sizeof(v));
    phi[1] = 1;

    for (int i = 2; i <= n; i++)
    {
        if (!v[i])
        {
            prime[++cnt] = v[i] = i;
            phi[i] = i - 1;
        }
        for (int j = 1; j <= cnt; j++)
        {
            if (prime[j] > v[i] || i * prime[j] > n)
                break;
            v[i * prime[j]] = prime[j];
            phi[i * prime[j]] = phi[i] * (i % prime[j] ? prime[j] - 1 : prime[j]);
        }
        // sumPhi[i] = sumPhi[i - 1] + phi[i];
    }
}
/*=================================================主函数*/
signed main()
{
    n = read();
    eular(n);
    for (int i = 1; i <= n; i++)
        ans += (n / i) * (n / i) * phi[i];
    printf("%lld
", ans);
    return 0;
}

最后

鸣谢 :

如果存在错误,感谢指出。

原文地址:https://www.cnblogs.com/Frather/p/14742662.html