这一生,其实就是不断在告别的|

莫比乌斯函数与莫比乌斯反演

https://www.luogu.com/article/vycu5sds

https://www.cnblogs.com/heyuhhh/p/11231502.html

https://www.luogu.com/article/qkowpfcc

前置

数论分块

简介

数论分块可以快速计算一些含有除法向下取整的和式。它主要运用富比尼定理,将 ni 相同的数打包计算。

引理

a,b,cZabc=abc

证明:

ab=ab+r(0r<1),则 abc=ab×1c=1c×(ab+r)=abc+rc=abc

形式一

求:i=1nni

我们知道有许多 ni 的值是一样的,而且它们是呈块状分布的。我们容易得到:对于每一个值相同的块,它的最后一个数是 nni

例题:UVA11526

海螺,海诺,唔,这个小海螺你要收好咯,能听到我隐藏版的歌声唷
#include <bits/stdc++.h>
#define int long long
using namespace std;
int T,n;
int H(int x){
int res = 0,l = 1,r;
while(l <= x){
r = x / (x / l);
res += (r - l + 1) * (x / l);
l = r + 1;
}
return res;
}
signed main(){
scanf("%lld",&T);while(T --){
scanf("%lld",&n);
printf("%lld\n",H(n));
}
return 0;
}

形式二

给定 k,求:i=1nkmodi

推导:原式 =i=1nki×ki=n×ki=1ni×ki。推导毕。

注意处理一下边界的细节问题。

例题 P2261 [CQOI2007] 余数求和

要藏好我的鱼尾巴,别被人类发现啦!
#include <bits/stdc++.h>
#define int long long
using namespace std;
int n,k;
int H(){
int res = 0,l = 1,r;
while(l <= min(n,k)){
r = k / (k / l);
if(r > n) res += (l + n) * (n - l + 1) / 2 * (k / l);
else res += (l + r) * (r - l + 1) / 2 * (k / l);
l = r + 1;
}
return res;
}
signed main(){
scanf("%lld%lld",&n,&k);
printf("%lld",n * k - H());
return 0;
}

形式三

求:i=1nf(i)×ni

对前半段的函数维护一个前缀和,再用整除分块处理后半段,两段相乘即可。

习题

1. P3935 Calculating

推导:

x=i=1spikif(x)=i=1s(ki+1),我们容易发现,f(x) 表示的其实就是 x 所有因子的个数,即 f(x)=i=1x[i | x]

ans=i=lrf(i)=i=1rf(i)i=1l1f(i)。对于前者 i=1rf(i) 的计算,我们可以利用另外一种解法,即用 g(i) 表示 i1r 中是多少个数的有因子 i,那么很明显 i=1rf(i)=i=1rg(i),同时 g(i)=ri,因此可得原式 =i=1rrii=1l1l1i

别害怕,黑夜只是白天的前奏
#include <bits/stdc++.h>
#define int long long
#define MOD 998244353
using namespace std;
int H(int n){
int res = 0,l = 1,r;
while(l <= n){
r = n / (n / l);
res += (r - l + 1) * (n / l);
res %= MOD;
l = r + 1;
}
return res;
}
signed main(){
int l,r;scanf("%lld%lld",&l,&r);
printf("%lld",(H(r) + MOD - H(l - 1)) % MOD);
return 0;
}

2. P2260 [清华集训2012] 模积和

注意题目要求 ij。我们令 nm(假如大于那就交换一下就行了)。

ans=i=1n(nmodi)j=1m(mmodj)i=1n(nmodi)×(mmodi)=i=1n(ni×ni)j=1m(mj×mj)i=1n(ni×ni)×(mi×mi)=(n×ni=1ni×ni)×(m×mi=1mi×mi)i=1n(n×mn×i×mim×i×ni+i2×ni×mi)=(n×ni=1ni×ni)×(m×mi=1mi×mi)(n2mn×i=1ni×mim×i=1ni×ni+i=1ni2×ni×mi)

OK 了,式子推完了,我们或许还不知道怎么求的是这一项:i=1ni2×ni×mi

我们依旧是分块去求,只不过我们要找的块是 nimi 都相等的块,所以把每次更改的 r 的值改成 min(n / (n / l),m / (m / l)) 即可。关于 i=1ni2,有一个结论,=n×(n+1)×(2×n+1)6,所以每次分完块后用前缀和的思想求一下区间的 i2 的和即可。

关于 i=1ni2=n×(n+1)×(2×n+1)6 的证明:
我们有 (n+2)×(n+1)×n3(n+1)×n×(n1)3=(n+1)×n
使用叠加法,我们有 1×2+2×3++n×(n+1)=(n+2)×(n+1)×n3
即有 12+22+n2+(1+2++n)=(n+2)×(n+1)×n3,移项,可得:
i=1ni2=n×(n+1)×(2×n+1)6
证毕。

预处理一下 6 在模数下的逆元以节省部分时间,其值为 3323403

你听,大海与夕阳之间藏着许多金色的旋律
#include <bits/stdc++.h>
#define MOD 19940417
#define int long long
using namespace std;
int n,m;
int H(int x){
int res = 0,l = 1,r;
while(l <= x){
r = x / (x / l);
res += (l + r) * (r - l + 1) / 2 % MOD * (x / l) % MOD,res %= MOD;
l = r + 1;
}
return res;
}
int H2(){
int res = 0,l = 1,r;
while(l <= n){
r = m / (m / l);
if(r > n) {res += (l + n) * (n - l + 1) / 2 % MOD * (m / l) % MOD,res %= MOD;}
else {res += (l + r) * (r - l + 1) / 2 % MOD * (m / l) % MOD,res %= MOD;}
l = r + 1;
}
return res;
}
int JD(int l,int r){
int a = r * (r + 1) % MOD * (2 * r + 1) % MOD * 3323403 % MOD;
int b = l * (l + 1) % MOD * (2 * l + 1) % MOD * 3323403 % MOD;
return (a - b + MOD) % MOD;
}
int H3(){
int res = 0,l = 1,r;
while(l <= n){
r = min(n / (n / l),m / (m / l));
res += JD(l - 1,r) * (n / l) % MOD * (m / l) % MOD,res %= MOD;
l = r + 1;
}
return res;
}
signed main(){
scanf("%lld%lld",&n,&m);if(n > m) swap(n,m);
int a = ((n * n - H(n)) % MOD + MOD) % MOD;
int b = ((m * m - H(m)) % MOD + MOD) % MOD;
int ans1 = a * b % MOD;
int c = n * n % MOD * m % MOD;
int d = m % MOD * H(n) % MOD;
int e = n % MOD * H2() % MOD;
int f = H3();
int ans2 = ((c - d - e + f) % MOD + MOD) % MOD;
printf("%lld",(ans1 - ans2 + MOD) % MOD);
return 0;
}

积性函数

定义

积性函数:积性函数是指对于所有互质的整数 ab 都有性质 f(ab)=f(a)f(b) 的数论函数,例如欧拉函数 φ(n),莫比乌斯函数 μ(n),因数个数函数 d(n)
完全积性函数:对于任意整数 ab 有性质 f(ab)=f(a)f(b) 的数论函数。

性质

f(n)g(n) 都是积性函数,那么以下函数也为积性函数:
h(x)=f(xp)h(x)=fp(x)h(x)=f(x)g(x)h(x)=d|xf(d)g(xd)

常见积性函数

单位函数 ϵ(n)=[n=1],别称为“对于狄利克雷卷积的乘法单位”。

幂函数 Idk(n)=nkId1(n) 通常简记为 Id(n)

常数函数 1(n)=1

因数个数 d(n)=d|n1

除数函数 σk(n)=d|ndkk=1 时为因数和函数,通常简记为 σnk=0 时为因数个数函数 σ0(n)

欧拉函数 φ(n)=i=1n[gcd(i,n)=1]

莫比乌斯函数 μ(n)={1n=10n (1)kk  n 

狄利克雷卷积

定义

定义两个数论函数 f(x),g(x) 的狄利克雷卷积为:h(x)=d|xf(d)g(xd)=ab=xf(a)g(b)。其和简记为 h=fg

性质

满足交换律,结合律,分配律。fg=gf(fg)h=f(gh)(f+g)h=fh+gh

f=g 的充要条件是 fh=gh,其中数论函数 h(x) 要满足 h(1)0

ϵ 为狄利克雷卷积的单位元,即对于所有的数论函数,有 (fϵ)(n)=f(n)

对于任意一个满足 f(x)0 的数论函数,如果有另一个数论函数 g(x) 满足 fg=ϵ,则称 g(x)f(x) 的逆元,且逆元唯一。

f,g 为积性函数,那么 fg 为积性函数。

证明:设两个积性函数 f(x)g(x),再记 h=fg
gcd(a,b)=1,则:h(a)=d1|af(d1)g(ad1),h(b)=d2|bf(d2)g(bd2)
所以:h(a)h(b)=d1|af(d1)g(ad1)d2|bf(d2)g(bd2)=d|abf(d)g(abd)=h(ab)
证毕。

ϵ=μ1ϵ(n)=d|nμ(d)d=11d(n)=d|n1σ=id1σ(n)=d|ndφ=μidφ(n)=d|ndμ(nd)

莫比乌斯函数

定义

μ 为莫比乌斯函数,其定义为:μ(n)={1n=10n (1)kk  n 

n 含有平方因子的含义为只要某个质因子出现的次数大于 1 次,μ(n) 就等于 0

性质

性质一

莫比乌斯函数是积性函数。

性质二

d|nμ(d)={1n=10n1,即可得 d|nμ(d)=ϵ(n),μ1=ϵ

证明:

n=i=1spici,n=i=1spi,则 d|nμ(d)=d|nμ(d)(因为含有平方因子的因数的 μ0=i=0sCsi(1)i=(1+(1))s(由 二项式定理 得到)。

由此可得只有在 s=0n=1 的时候取到值 1,否则为 0,于是 d|nμ(d)=[n=1]=ϵ(n) 以及 μ1=ϵ

线性筛求莫比乌斯函数

根据 μ 是积性函数求解即可,基本所有的积性函数可以用线性筛解决。

我可不会变成海上的泡沫,我是可以再来一次的人鱼朵朵!
void getMu(){
vis[1] = 1,mu[1] = 1;
for(int i = 2;i <= n;i ++){
if(!vis[i]) Prime[++cnt] = i,mu[i] = -1;
for(int j = 1;j <= cnt and i * Prime[j] <= n;j ++){
vis[i * Prime[j]] = 1;
if(i % Prime[j] == 0){
mu[i * Prime[j]] = 0;
break;
}
mu[i * Prime[j]] = -mu[i];
}
}
}

莫比乌斯变换

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

根据 μ1=ϵ,可得 f=fϵ=f(μ1)=(f1)μ

形式一

如果有 f(n)=d|ng(d),那么有 g(n)=d|nμ(d)f(nd)

这种形式下,数论函数 f(n) 称为数论函数 g(n) 的莫比乌斯变换,数论函数 g(n) 称为数论函数 f(n) 的莫比乌斯逆变换(反演)。容易看出,数论函数 g(n) 的莫比乌斯变换,就是将其与常数函数 1 进行狄利克雷卷积。

证明:
方法一:运用卷积
原问题为:已知 f=g1,求证 g=fμ
易知 fμ=g1μ,因此 fμ=g。(1μ=ϵ
方法二:对原式做数论变换
d|nμ(d)f(nd)=d|nμ(d)k|ndg(k)=k|ng(k)d|nkμ(d)=g(n)
第一步是将已知条件带入得到。第二步是变换求和顺序得到(相当于前者先循环 d 在循环 k,后者是先循环 k 在循环 d)。第三部,由性质二可得,只有 n=k 的时候后者才为 1,其它情况为 0,故只有在 k=n 的时候才能取到值,即 g(n)
证毕。

形式二

如果有 f(n)=n|dg(d),那么有 g(n)=n|dμ(dn)f(d)

证明
n|dμ(dn)f(d)=k=1+μ(k)f(kn)=i=1+μ(k)kn|dg(d)=n|dg(d)k|dnμ(k)=g(n)

拓展

证明 φ1=id

n 分解质因数得到 n=i=1spici。因为 φ 是积性函数,故只要证明当 n=pcφ1=d|nφ(d)=id 成立即可。

因为 p 时质数,所以 d=p0,p1pc。于是我们可得 φ1=d|nφ(d)=i=0cφ(pi)=1+p0×(p1)+p1×(p1)+pc×(p1)=pc=id

该式子两侧同时卷 μ 可得到 φ(n)=d|ndμ(nd)

反演

莫比乌斯反演结论

[gcd(i,j)=1]=d|gcd(i,j)μ(d)

证明:运用莫比乌斯函数性质二,其正确性显然。证毕。

同时我们也可以得到 [gcd(i,j)=1]=ϵ(gcd(i,j))

欧拉反演结论

gcd(i,j)=d|gcd(i,j)φ(d)

证明详见 我的博客——欧拉函数与欧拉定理

常见的几种反演形式

以下默认 nm

形式一

i=1nj=1m[gcd(i,j)=1]=i=1nj=1md|id|jμ(d)=x=1ni=1nj=1m[d | i][d | j]μ(d)=d=1nμ(d)ndmd

首先 O(n) 预处理出莫比乌斯函数前缀和,后者二元数论分块即可,单次求解 O(n)

习题

1. P2522 [HAOI2011] Problem b

相当于求 i=abj=cd[gcd(i,j)=k],根据容斥原理,我们可以把它分成四部分,每一部分相当于求 i=1nj=1m[gcd(i,j)=k]=i=1nkj=1mk[gcd(i,j)=1],然后带入形式一求值,至于分成哪四部分,可以看如图:

外祖母说,最完美的天籁,用热忱和爱才能唱出来!
#include <bits/stdc++.h>
#define N 50004
using namespace std;
int vis[N],mu[N],Prime[N],cnt;
void getMu(){
vis[1] = 1,mu[1] = 1;
for(int i = 2;i <= 50000;i ++){
if(!vis[i]) Prime[++cnt] = i,mu[i] = -1;
for(int j = 1;j <= cnt and Prime[j] * i <= 50000;j ++){
vis[i * Prime[j]] = 1;
if(i % Prime[j] == 0){
mu[i * Prime[j]] = 0;
break;
}
mu[i * Prime[j]] = -mu[i];
}
}
for(int i = 2;i <= 50000;i ++) mu[i] += mu[i - 1];
}
int JD(int n,int m){
if(n > m) swap(n,m);
int res = 0,l = 1,r;
while(l <= n){
r = min(n / (n / l),m / (m / l));
res += (mu[r] - mu[l - 1]) * (n / l) * (m / l);
l = r + 1;
}
return res;
}
int main(){
getMu();int T;scanf("%d",&T);while(T --){
int a,b,c,d,k;scanf("%d%d%d%d%d",&a,&b,&c,&d,&k);
printf("%d\n",JD(b / k,d / k) - JD(b / k,(c - 1) / k) - JD((a - 1) / k,d / k) + JD((a - 1) / k,(c - 1) / k));
}
return 0;
}

形式二

i=1nj=1m[gcd(i,j)Prime]=kPrimei=1nj=1m[gcd(i,j)=k]=kPrimed=1nknkdmkdμ(d)=T=1nnTmTk|TkPrimeμ(Tk)

最后一步通过换元令 T=kd 得到。最后一步变换我们实现了可预处理 k|TkPrimeμ(Tk) 的效果,降低了复杂度。预处理方法就是先筛出来所有质数,然后枚举所有质数的倍数即可,处理出来它的前缀和。预处理复杂度 O(nlnn),单次求解 O(n)

习题

1. P2257 YY的GCD & 双倍经验 SP4491 PGCD - Primes in GCD Table

带着歌声,我们一起去往星辰大海吧!
#include <bits/stdc++.h>
#define N 10000000
#define int long long
using namespace std;
int T,n,m,vis[N + 5],mu[N + 5],Prime[N + 5],cnt,f[N + 5];
void getMu(){
vis[1] = 1,mu[1] = 1;
for(int i = 2;i <= N;i ++){
if(!vis[i]) Prime[++cnt] = i,mu[i] = -1;
for(int j = 1;j <= cnt and i * Prime[j] <= N;j ++){
vis[i * Prime[j]] = 1;
if(i % Prime[j] == 0){
mu[i * Prime[j]] = 0;
break;
}
mu[i * Prime[j]] = -mu[i];
}
}
for(int i = 1;i <= cnt;i ++){
for(int j = 1;j * Prime[i] <= N;j ++){
f[j * Prime[i]] += mu[j];
}
}
for(int i = 1;i <= N;i ++) f[i] += f[i - 1];
}
int H(int x){
int res = 0,l = 1,r;
while(l <= x){
r = min(n / (n / l),m / (m / l));
res += (f[r] - f[l - 1]) * (n / l) * (m / l);
l = r + 1;
}
return res;
}
signed main(){
getMu();
scanf("%lld",&T);while(T --){
scanf("%lld%lld",&n,&m);
if(n > m) swap(n,m);
printf("%lld\n",H(n));
}
return 0;
}

形式三

i=1nj=1mgcd(i,j)=i=1nj=1md|gcd(i,j)φ(d)=d=1nφ(d)i=1n[d | i]j=1m[d | j]=d=1nndmdφ(d)

O(n) 预处理出前缀和 φ(d),单次求解 O(n)

习题

1. SP26017 GCDMAT - GCD OF MATRIX

类似形式一习题一容斥,把它分成四部分。

你小时候都一个人长大,没有伙伴儿么,我都有两条小鱼呢。
#include <bits/stdc++.h>
#define N 50004
#define int long long
#define MOD 1000000007
using namespace std;
int vis[N],phi[N],Prime[N],cnt;
void getPhi(){
vis[1] = 1,phi[1] = 1;
for(int i = 2;i <= 50000;i ++){
if(!vis[i]) Prime[++cnt] = i,phi[i] = i - 1;
for(int j = 1;j <= cnt and i * Prime[j] <= 50000;j ++){
vis[i * Prime[j]] = 1;
if(i % Prime[j] == 0){
phi[i * Prime[j]] = phi[i] * Prime[j];
break;
}
phi[i * Prime[j]] = phi[i] * (Prime[j] - 1);
}
}
for(int i = 1;i <= 50000;i ++) phi[i] = (phi[i] + phi[i - 1]) % MOD;
}
int JD(int n,int m){
if(n > m) swap(n,m);
int res = 0,l = 1,r;
while(l <= n){
r = min(n / (n / l),m / (m / l));
res += (phi[r] - phi[l - 1] + MOD) % MOD * (n / l) * (m / l) % MOD,res %= MOD;
l = r + 1;
}
return res;
}
signed main(){
int T,n,m;scanf("%lld%lld%lld",&T,&n,&m);getPhi();while(T --){
int a,b,c,d;scanf("%lld%lld%lld%lld",&a,&b,&c,&d);a -= 1,b -= 1;
printf("%lld\n",((JD(c,d) - JD(a,d) - JD(c,b) + JD(a,b)) % MOD + MOD) % MOD);
}
return 0;
}

形式四

首先我们先了解一个结论:d(ij)=x|iy|j[gcd(x,y)=1]

证明
由于 d 函数是积性函数,所以我们不妨将每一个质因子分开考虑:
i,j 分别含有 a,b 个质因子 p,显然等式左侧可以选择的因子的个数为 a+b+1 个。对于右侧而言,显然也有 a+b+1 中,即要么 x=1y 的选择方法为 b 个;要么 y=1x 的选择方法为 a 个,要么二者都为 1。因此等式两边相等。
证毕。

6。啥时候想回来补就回来补。

posted @   Joy_Dream_Glory  阅读(37)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起