莫比乌斯反演小结
在学反演之前需要先懂得莫比乌斯函数及其含义。
莫比乌斯函数
它其实只是一个由容斥系数所构成的函数。
设正整数 N 按照算术基本定理分解质因数为 N =
,
定义函数
称μ(N) 为 莫比乌斯函数。
通俗地讲,当N包含相等的质因子时,μ(N) = 0。当N的所有因子各不相等时,若N有偶数个质因子μ(N) = 1, 若N有奇数个质因子,μ(N) = -1。
如果只求一项莫比乌斯函数,则分解质因数即可计算。 若求1~N的每一项莫比乌斯函数可以用线性筛。
质因数分解:
#include<bits/stdc++.h>
#define up(i, a, b) for(int i = a; i <= b; i++)
#define down(i, a, b)for(int i = a;i >= b; i--)
#define mem(a, b)memset(a, b, sizeof(a))
#define inf 0x3f3f3f3f
//#define int long long
using namespace std;
const int maxn = 1e5 + 700;
int tot = 0, a[maxn], b[maxn];
void factor(int n){
int temp, i, now;
temp = (int)((double) sqrt(n) + 1);
now = n;
for(i = 2;i <= temp; i++){
if(now % i == 0){
a[++tot] = i;
b[tot] = 0;
while(now % i == 0){
++b[tot];
now /= i;
}
}
}
if(now != 1){
a[++tot] = now;
b[tot] = 1;
}
}
signed main()
{
int n;cin >> n;
factor(n);
up(i, 1, tot){
printf("%d^%d\n", a[i], b[i]);
}
return 0;
}
线性筛莫比乌斯函数:
#include<bits/stdc++.h>
#define up(i, a, b) for(int i = a; i <= b; i++)
#define down(i, a, b)for(int i = a;i >= b; i--)
#define mem(a, b)memset(a, b, sizeof(a))
#define inf 0x3f3f3f3f
//#define int long long
using namespace std;
const int maxn = 1e5 + 700;
int mu[maxn], prim[maxn], vis[maxn] = {1,1}, cnt = 0;
void get_mu(int n)
{
mu[1]=1;
for(int i=2;i<=n;i++)
{
if(!vis[i]){prim[++cnt]=i;mu[i]=-1;}
for(int j=1;j<=cnt&&prim[j]*i<=n;j++)
{
vis[prim[j]*i]=1;
if(i%prim[j]==0)break;
else mu[i*prim[j]]=-mu[i];
}
}
}
signed main()
{
int n;cin >> n;
get_mu(n);
// up(i, 1, 10)cout << prim[i] << endl;
return 0;
}
莫比乌斯反演
定理:F(n)和f(n)是定义在非负整数集合上的两个函数,并且满足条件:
d|n : d的为n的因子
那么存在一个结论:
另一种形式:
满足条件:
那么存在:
证明略。
记住这里的反演公式后,求可以解决一些有关的题目了。
例题:
(待补)
1. Zap (BZOJ1101)
https://vjudge.net/problem/%E9%BB%91%E6%9A%97%E7%88%86%E7%82%B8-1101
2.Problem H. Curious(2020 吉林省赛)Gym - 102800H
https://vjudge.z180.cn/problem/Gym-102800H
3.