当前位置:网站首页>积性函数与迪利克雷卷积
积性函数与迪利克雷卷积
2022-04-23 06:21:00 【Zimba_】
前言:
早睡早起身体好!今天更一下积性函数。
积性函数的定义:
什么是积性函数呢?(又叫乘性函数)
先讲一个更宽泛的概念,算术函数。(算术函数又称数论函数)
算数函数,就是对所有正整数定义的函数,也就是定义域为正整数的函数。
而积性函数,则是一种特殊的算术函数。
对于函数 f ( x ) f(x) f(x),
若满足 f ( 1 ) = 1 f(1)=1 f(1)=1,
且对于任意互质的正整数 p p p和 q q q,满足 f ( p q ) = f ( p ) f ( q ) f(pq)=f(p)f(q) f(pq)=f(p)f(q),
则称 f ( x ) f(x) f(x)为积性函数。
而对于函数 f ( x ) f(x) f(x),
若满足 f ( 1 ) = 1 f(1)=1 f(1)=1,
且对于任意的正整数 p p p和 q q q,满足 f ( p q ) = f ( p ) f ( q ) f(pq)=f(p)f(q) f(pq)=f(p)f(q),
则称 f ( x ) f(x) f(x)为完全积性函数。
(这不是我们这里要讲的重点)
我们主要来讲积性函数,现在继续来看这个定义。
根据唯一分解定理,我们可以将 x x x分解得到 x = p 1 k 1 p 2 k 2 … p n k n x=p_{1}^{k_{1}}p_{2}^{k_{2}}…p_{n}^{k_{n}} x=p1k1p2k2…pnkn。
则有 f ( x ) = f ( p 1 k 1 ) f ( p 2 k 2 ) … f ( p n k n ) f(x)=f(p_{1}^{k_{1}})f(p_{2}^{k_{2}})…f(p_{n}^{k_{n}}) f(x)=f(p1k1)f(p2k2)…f(pnkn)。
也就是说,当我们想要定义一个积性函数时,我们只要将质数的幂次都定义好,那么所有数的函数值都已经得到了。
现在,我们可以自己捏一个没什么用的积性函数出来了。
我们定义 f ( x ) = { 1 , x = 1 p × k , x = p k , p 是 质 数 , k 是 正 整 数 f(x)=\begin{cases} 1 & \text{,}x=1 \\ p\times k & \text{,}x=p^{k},p是质数,k是正整数 \end{cases} f(x)={
1p×k,x=1,x=pk,p是质数,k是正整数
然后再说明当 a ⊥ b a\perp b a⊥b时, f ( a b ) = f ( a ) f ( b ) f(ab)=f(a)f(b) f(ab)=f(a)f(b)即可。( a ⊥ b a\perp b a⊥b表示 a a a与 b b b互质)
没什么用的积性函数就捏好了。
常见的积性函数:
现在讲一些有用的积性函数。
单位函数和常数函数:
先来两个显然的积性函数。
第一个是单位函数 e ( n ) = [ n = 1 ] e(n)=[n=1] e(n)=[n=1],
(中括号 [ ] [\;] []表示逻辑运算,当括号内表达式成立,则值为 1 1 1,反之为 0 0 0)
也就是说,当 x = 1 x=1 x=1时, e ( x ) = 1 e(x)=1 e(x)=1;当 x ≠ 1 x\neq 1 x=1时, e ( x ) = 0 e(x)=0 e(x)=0。
可以理解它为单位元,后面会有更深的理解。
第二个是常数函数 1 ( n ) = 1 1(n)=1 1(n)=1。
咳咳,这里第一个 1 1 1是函数符号,不要问我为什么这么表示。
这个函数就是,对于任意的 x x x,均满足 1 ( x ) = 1 1(x)=1 1(x)=1。
当然这两个函数都是完全积性函数,这不是重点,我们继续。
欧拉函数 φ ( n ) \varphi(n) φ(n):
欧拉函数 φ ( n ) \varphi (n) φ(n),表示小于等于 n n n且与 n n n互质的数的个数。
比如小于等于 6 6 6,并且和 6 6 6互质的数有 1 1 1和 5 5 5,所以 φ ( 6 ) = 2 \varphi(6)=2 φ(6)=2。
这个函数的用处就多了去了,要单独开一篇博客讲,这里就只证明一下它是积性函数。
因为不会证,所以这里要用一下循环论证。
姑且记住它是积性函数吧,留的坑等讲它的时候再填。
提一点, φ ( p k ) = p k − p k − 1 \varphi(p^{k})=p^{k}-p^{k-1} φ(pk)=pk−pk−1,其中 p p p是质数, k k k是正整数。
因子和与因子个数:
因子和函数 σ ( n ) \sigma(n) σ(n),表示 n n n的因子和,有 σ ( n ) = ∑ d ∣ n d \sigma(n)=\sum_{d|n}d\; σ(n)=∑d∣nd。
因子个数函数 τ ( n ) \tau (n) τ(n),表示 n n n的因子和,有 τ ( n ) = ∑ d ∣ n 1 \tau (n)=\sum_{d|n}1\; τ(n)=∑d∣n1。
证明这两个是积性函数,有兴趣可以自证。
这里 ∑ d ∣ n \sum_{d|n} ∑d∣n就是枚举 n n n的所有因子 d d d。
看公式也比较明白。因子和就是枚举所有因子 d d d,然后把所有因子 d d d加起来。因子个数就是枚举所有的因子,然后对于每个因子都加一个 1 1 1。
同样举一下,
σ ( p k ) = 1 + p + p 2 + … + p k = p k + 1 − 1 p − 1 \sigma(p^{k})=1+p+p^{2}+…+p^{k}=\frac{p^{k+1}-1}{p-1} σ(pk)=1+p+p2+…+pk=p−1pk+1−1,
τ ( p k ) = k + 1 \tau(p^{k})=k+1 τ(pk)=k+1,
这两个都比较容易得出来。
莫比乌斯函数 μ ( n ) \mu(n) μ(n):
又是一个大神级别的函数,也是要单独开一篇来讲的,先说定义。
μ ( n ) = { 1 , x = 1 ( − 1 ) r , x = p 1 p 2 … p r , 即 x 的 所 有 素 因 子 次 数 均 为 1 , 其 中 r 表 示 素 因 子 个 数 0 , 其 他 情 形 , 即 x 存 在 平 方 因 子 \mu(n)=\begin{cases} 1 & \text{,}x=1 \\ (-1)^{r} & \text{,}x=p_{1}p_{2}…p_{r},即x的所有素因子次数均为1,其中r表示素因子个数 \\ 0 & \text{,}其他情形,即x存在平方因子 \end{cases} μ(n)=⎩⎪⎨⎪⎧1(−1)r0,x=1,x=p1p2…pr,即x的所有素因子次数均为1,其中r表示素因子个数,其他情形,即x存在平方因子
这个定义就离谱,后面会讲它的由来的。
现在也同样只要知道它是积性函数。
积性函数筛:
要知道一点,积性函数都是可以 o ( n ) o(n) o(n)筛出来的。
(当然,只需要求某一个函数值的时候,是可以有差不多 o ( n ) o(\sqrt{n}) o(n)的做法更快得到的,而筛就是筛出 1 1 1到 n n n的积性函数值)
那么具体怎么筛?
首先,积性函数筛都是建立在 o ( n ) o(n) o(n)素数筛的基础上的。
先讲线性素数筛。
线性素数筛就是在埃式筛的基础上进行了改进——让每一个数只被一个数给筛掉。
我们知道,埃式筛是用每一个素数,去筛它的倍数。而线性筛,则要保证每个数只被它最小的素因子给筛掉。
直接上代码。
int notPrime[MAXN],prime[MAXN],tot;
void getPrime(int n)
{
notPrime[1]=1;
for(int i=2;i<=n;i++)
{
if(!notPrime[i])prime[tot++]=i;
for(int j=0;j<tot&&i*prime[j]<=n;j++)
{
notPrime[i*prime[j]]=1;
if(i%prime[j]==0)break;
}
}
}
解释一下这个代码的原理。
首先,所有的合数都可以表示成另一个数乘上它的最小素因子。
所有我们得到一个数后,只要枚举选用哪个素数作为它的最小素因子即可。
那么这个代码,先是枚举每一个数 i i i,如果没有被筛过,那就丢到素数列表 p r i m e [ ] prime[] prime[]里。
然后对于这个数 i i i,我们还要做的一件事,就是枚举它要乘上的最小素因子 p r i m e [ j ] prime[j] prime[j]。
当 i i i这个数,能够整除当前这个素因子,那么就不能再往后枚举了。因为当前这个因子是 i i i的一个素因子了,如果我们再往后枚举的话,就比这个素因子要大了,那就不是用最小素因子筛的了。
到这里代码就结束了。
现在我们来讲积性函数筛。
其实就是在素数筛的基础上进行改进。
首先,对于积性函数 f ( x ) f(x) f(x),我们要具备快速算出 f ( p k ) f(p^{k}) f(pk)的能力,就跟我们之前定义的时候说的一样,然后根据积性函数的性质,来得到其他的函数值。
做的时候,我们在筛出每个数的位置算它的积性函数值 f ( x ) f(x) f(x)。
首先,筛出质数的时候,我们直接把质数p的函数值 f ( p ) f(p) f(p)赋上。
然后在循环里筛合数时,有两种情况,一种是 i i i不能被 p r i m e [ j ] prime[j] prime[j]整除的,那么就有 g c d ( i , p r i m e [ j ] ) = 1 gcd(i,prime[j])=1 gcd(i,prime[j])=1成立,得到 f ( i × p r i m e [ j ] ) = f ( i ) f ( p r i m e [ j ] ) f(i\times prime[j])=f(i)f(prime[j]) f(i×prime[j])=f(i)f(prime[j])。
那么就只剩最后一种情况,就是 i i i能被 p r i m e [ j ] prime[j] prime[j]整除的情况,这时候我们处理出 i i i中最小素因子的幂次 l o w i low_{i} lowi,就有 g c d ( i l o w i , p r i m e [ j ] × l o w i ) gcd(\frac{i}{low_{i}},prime[j]\times low_{i}) gcd(lowii,prime[j]×lowi),就可以得到 f ( i × p r i m e [ j ] ) = f ( i l o w i ) f ( p r i m e [ j ] × l o w i ) f(i\times prime[j])=f(\frac{i}{low_{i}})f(prime[j]\times low_{i}) f(i×prime[j])=f(lowii)f(prime[j]×lowi)。
最后,想办法处理 l o w i low_{i} lowi就好了,这个也可以在筛的时候处理。因为我们是拿最小素因子筛的,所以有 l o w ( i × p r i m e [ j ] ) = l o w ( i ) × p r i m e [ j ] low(i\times prime[j])=low(i)\times prime[j] low(i×prime[j])=low(i)×prime[j]。
到这里,就大功告成了。
上模板。(这个板子现写的,可能不会有问题)
int notPrime[MAXN],prime[MAXN],tot,low[MAXN];
int f[MAXN];
void getFunc(int n)
{
notPrime[1]=f[1]=low[1]=1;
for(int i=2;i<=n;i++)
{
if(!notPrime[i])low[i]=prime[tot++]=i,f[i]=(素数直接计算);
for(int j=0;j<tot&&i*prime[j]<=n;j++)
{
notPrime[i*prime[j]]=1;
if(i%prime[j])
{
low[i*prime[j]]=prime[j];
f[i*prime[j]]=f[i]*f[prime[j]];
}
else
{
low[i*prime[j]]=low[i]*prime[j];
if(low[i]==i)f[i*prime[j]]=(素数幂次直接计算);
else f[i*prime[j]]=f[i/low[i]]*f[prime[j]*low[i]];
break;
}
}
}
}
上面是一般的积性函数求法。
现在讲讲特殊的,欧拉函数和莫比乌斯函数的筛法。
原理还是一样,只不过有些地方比较便捷。
先说莫比乌斯函数。
首先质数 p p p的函数值 μ ( p ) = − 1 \mu(p)=-1 μ(p)=−1。
那么当 i i i不被 p p p整除时,求法一样,直接用积性函数性质, μ ( i p ) = μ ( i ) μ ( p ) = − μ ( i ) \mu(ip)=\mu(i)\mu(p)=-\mu(i) μ(ip)=μ(i)μ(p)=−μ(i)。
当 i i i被 p p p整除时,(我们知道,当 x x x存在平方因子时, μ ( x ) = 0 \mu(x)=0 μ(x)=0),就可以大胆的赋上 0 0 0了。
模板:
int notPrime[MAXN],prime[MAXN],tot;
int mu[MAXN];
void initMu(int n)
{
notPrime[1]=mu[1]=1;
for(int i=2;i<=n;i++)
{
if(!notPrime[i])prime[tot++]=i,mu[i]=-1;
for(int j=0;j<tot&&i*prime[j]<=n;j++)
{
notPrime[i*prime[j]]=1;
if(i%prime[j])mu[i*prime[j]]=-mu[i];
else {
mu[i*prime[j]]=0;break;}
}
}
}
然后是欧拉函数,
质数时, φ ( p ) = p − 1 \varphi(p)=p-1 φ(p)=p−1。
然后它有个神奇的性质,对于一个质数 p p p,若 p ∣ i p|i p∣i,则 φ ( i p ) = φ ( i ) p \varphi(ip)=\varphi(i)p φ(ip)=φ(i)p;若 p p p不整除 i i i,则 φ ( i p ) = φ ( i ) ( p − 1 ) \varphi(ip)=\varphi(i)(p-1) φ(ip)=φ(i)(p−1)。
然后根据这个,又可以很容易地写出欧拉函数筛。
int notPrime[MAXN],prime[MAXN],tot;
int phi[MAXN];
void initPhi(int n)
{
notPrime[1]=phi[1]=1;
for(int i=2;i<=n;i++)
{
if(!notPrime[i])prime[tot++]=i,phi[i]=i-1;
for(int j=0;j<tot&&i*prime[j]<=n;j++)
{
notPrime[i*prime[j]]=1;
if(i%prime[j])phi[i*prime[j]]=phi[i]*(prime[j]-1);
else {
phi[i*prime[j]]=phi[i]*prime[j];break;}
}
}
}
积性函数筛讲完了。
迪利克雷卷积:
在讲之前,再给出几个数论函数。(注意数论函数和积性函数的区别)
i d ( n ) = n id(n)=n id(n)=n,表示自身函数,函数值等于自变量本身。
ω ( n ) = ∑ p ∣ n 1 \omega(n)=\sum_{p|n}1 ω(n)=∑p∣n1,其中 p p p是素数,函数值表示 n n n的素因子个数。
开讲开讲。
迪利克雷卷积运算是数论函数的重要运算法则。
对,是运算法则,就像加减乘除一样的运算法则。
而且是函数的运算法则,运算结果也是一个函数。
你可以这么理解,这是专门为数论函数而建立的一种运算机制。
我们将数论函数 f f f和数论函数 g g g,进行迪利克雷卷积运算后,得到一个新的数论函数 h = f ∗ g h=f*g h=f∗g。(这里的 ∗ * ∗不是乘号,而是卷积运算的符号)
那么怎么个运算法呢。
那就是卷积的定义式 h ( n ) = ( f ∗ g ) ( n ) = ∑ d ∣ n f ( d ) g ( n d ) = ∑ d ∣ n f ( n d ) g ( d ) h(n)=(f*g)(n)=\sum_{d|n}f(d)g(\frac{n}{d})=\sum_{d|n}f(\frac{n}{d})g(d) h(n)=(f∗g)(n)=∑d∣nf(d)g(dn)=∑d∣nf(dn)g(d)。
现在来看这个式子, ∑ d ∣ n \sum_{d|n} ∑d∣n应该不陌生了,就是枚举因子。
我们回过来看前面的两个式子。
因子个数 τ ( n ) = ∑ d ∣ n 1 \tau (n)=\sum_{d|n}1\; τ(n)=∑d∣n1,我们发现这个函数其实就是两个常数函数通过卷积运算得到的。
我们就得到了一个式子 τ = 1 ∗ 1 \tau=1*1 τ=1∗1。
那么同理,再看因子和 σ ( n ) = ∑ d ∣ n d \sigma(n)=\sum_{d|n}d σ(n)=∑d∣nd,就有了 σ = 1 ∗ i d \sigma=1*id σ=1∗id。
到这里,应该了解了一些简单的卷积运算。
还要知道几个关于迪利克雷卷积运算的性质。
首先,它满足交换律,结合律。
然后,对于任意数论函数 f f f,有 f ∗ e = f f*e=f f∗e=f,即单位函数是一个单位元。
还有,若 f f f是积性函数,且 g g g是积性函数,则 f ∗ g f*g f∗g也是积性函数。
卷积运算大概就是这样了。
现在再罗列一些函数之间的卷积关系。
τ = 1 ∗ 1 \tau=1*1 τ=1∗1
σ = 1 ∗ i d \sigma=1*id σ=1∗id
1 ∗ μ = e 1*\mu=e 1∗μ=e
φ ∗ 1 = i d \varphi*1=id φ∗1=id
φ = i d ∗ μ \varphi=id*\mu φ=id∗μ
前两个式子前面讲过了,就不讲了。
你会发现第三个式子是一个神奇的式子,莫比乌斯函数卷上常数函数居然是单位元,换句话说, μ \mu μ和 1 1 1互为逆元。
其实这就是我们前面埋的一个坑,关于莫比乌斯函数那离谱的定义。
你可以理解成,它就是用来构造成常数函数的逆元的,这样做就可以实现莫比乌斯反演,后面一章博客会讲。
这样一来,还可以再得到一些式子,例如 τ ∗ μ = 1 \tau*\mu=1 τ∗μ=1, σ ∗ μ = i d \sigma*\mu=id σ∗μ=id等等,即在等式两边同时乘上 μ \mu μ与 1 1 1抵消掉。
我们再看最后两个式子,其实就是同一个式子,根据前面 1 1 1和 μ \mu μ的逆元关系进行了变换。
至于为什么 φ = i d ∗ μ \varphi=id*\mu φ=id∗μ,这个式子很重要,会在后面的莫比乌斯反演里讲。
这课码了6000字,难顶,终于讲完了。
版权声明
本文为[Zimba_]所创,转载请带上原文链接,感谢
https://blog.csdn.net/weixin_43785386/article/details/104489219
边栏推荐
- van-uploader上传图片实现过程、使用原生input实现上传图片
- 推导式与正则式
- el-date-picker中自定义快捷选项picker-options,动态设置禁用日期
- Lead the industry trend with intelligent production! American camera intelligent video production platform unveiled at 2021 world Ultra HD Video Industry Development Conference
- 记录一个查询兼容性的网站,String.replaceAll()兼容性报错
- 可视化之路(十)分割画布函数详解
- 数论之拓展欧几里得
- [牛客练习赛68]牛牛的粉丝(矩阵快速幂之循环矩阵优化)
- Applet newline character \ nfailure problem resolution - Daily pit stepping
- Intelligent communication solution of Hainan Phoenix Airport
猜你喜欢
随机推荐
LATEX公式注意事项
可视化之路(十一)matplotlib颜色详解
[牛客练习赛68]牛牛的粉丝(矩阵快速幂之循环矩阵优化)
可视化常见绘图(五)散点图
小程序换行符\n失效问题解决-日常踩坑
Intelligent communication solution of Hainan Phoenix Airport
Applet newline character \ nfailure problem resolution - Daily pit stepping
数论之阶与原根讲解
Lead the industry trend with intelligent production! American camera intelligent video production platform unveiled at 2021 world Ultra HD Video Industry Development Conference
PyTorch 12. Hook usage
免费开源智能充电桩物联网SAAS云平台
可视化常见问题解决方案(八)共享绘图区域问题解决方案
特殊成员与魔法方法
技能点挖坑
青龙面板拉库命令更新【2022/4/20】收藏不走丢
技术小白的第一篇(表达自己)
[COCI]Lampice (二分+树分治+字符串哈希)
Typora操作技巧说明(一)
Machine vision series (01) -- Overview
ESP32学习-向工程项目添加文件夹