一. 数论函数基础
数论函数:满足值域为整数的函数。
本文下述的数若无特殊说明均为整数。
若无特殊说明则钦定
n=k∏i=1peii,pi∈P。P 表示质数集合,pi 互不相同。
介绍几个常见的数论函数:
I(n):恒等函数,无论 n 是多少,其永远等于 1。
ϵ(n):元函数,当 n=1 是值为 1,否则为 0。它是狄利克雷卷积的单位元。
id(n):单位函数,无论 n 是多少,其值永远等于 n。
φ(n):欧拉函数,表示小于 n 的整数中与 n 互质的数的个数。
μ(n):莫比乌斯函数,定义后文讲述。
积性函数
定义:对于函数 f,若 n⊥m(即 n,m 互质)时有 f(nm)=f(n)f(m),则函数 f 为积性函数。
完全积性函数:对于函数 f,有任意整数 n,m 有 f(nm)=f(n)f(m)。
显然 I(n),ϵ(n),id(n) 都是完全积性函数。
显然完全积性函数是积性函数中的一种。
积性函数 f 有很多特殊性质:
二. 欧拉函数
欧拉函数 φ(n) 是积性函数且不是完全积性函数。
证明欧拉函数 φ 是积性函数
知乎上这个问题有许多清晰的解法。这里给出其中一种。
首先证明一个重要定理:φ(n)=nk∏i=1(pi−1pi)。
设 1∼n 中与 n 至少有 i 个相同质数因子的数有 Fi(n) 个。
显然 F0(n)=n。
F1(n)=k∑i=1npi。
F2(n)=∑1≤i<j≤knpipj。
以下同理。
考虑容斥原理,得
φ(n)=k∑i=0(−1)iFi(n)=n(1−k∑i=11pi+∑1≤i<j≤k1pipj−⋯)
容易发现式子即 φ(n)=nk∏i=1(pi−1pi)。
有此定理后证明 φ(n) 是积性函数不难。
设 n⊥m,n=k∏i=1peii,m=k′∏i=1qEii。
∴φ(n)=nk∏i=1(pi−1pi),φ(m)=mk′∏i=1(qi−1qi)。
φ(nm)=nmk∏i=1(pi−1pi)k′∏i=1(qi−1qi)=nm∏p|nmp−1p=φ(n)φ(m)
证毕。
欧拉函数的一些定理:
- φ(n)=nk∏i=1(pi−1pi)
此定理等同于:φ(n)=∏pk||npk−1(p−1)。
三. 狄利克雷卷积
对于两个数论函数 f(n),g(n),其狄利克雷卷积写作 (f∗g)(n),其中 f∗g 可以看作是函数名称。
定义:(f∗g)(n)=∑d|nf(d)g(nd)。
显然狄利克雷卷积满足交换律、结合律、分配律。
设 f,g 为积性函数,h(n)=∑d|nf(d)g(nd)。
设 n,m,n⊥m。
h(n)h(m)=∑a|nf(a)g(na)∑b|mf(b)g(mb)=∑a∣n∑b∣mf(a)f(b)g(na)g(mb)
∵n⊥m,∴∀a|n,∀b|m,a⊥b。
∵a⊥b,∴{a:a∣n}∪{b:b∣m}={d:d∣nm}
h(n)h(m)=∑a|n∑b|mf(ab)g(nmab)=∑d|nmf(d)g(nmd)=h(nm)。
证毕。
逆:当 f∗g=ϵ,f,g 互逆。
令 f 为积性函数,欲证 ∀n⊥m,g(nm)=g(n)g(m)。
考虑数学归纳法。
- nm=1
g(1)=1,显然成立。
- nm>1
钦定当 n′m′<nm 时结论成立。
g(nm)=∑d|nmf(d)g(nmd)−∑d∣nm,d≠1f(d)g(nmd)=ϵ(nm)−∑d∣nm,d≠1f(d)g(nmd)=−∑d|nm,d≠1f(d)g(nmd)=−∑a|n,b|m,ab≠1f(ab)g(nmab)=−∑a|n,b|m,ab≠1f(a)f(b)g(na)g(mb)=f(1)f(1)g(n)g(m)−∑a|n,b|mf(a)f(b)g(na)g(mb)=g(n)g(m)−⎛⎝∑a|nf(a)g(na)⎞⎠⎛⎝∑b|mf(b)g(mb)⎞⎠=g(n)g(m)−ϵ(n)ϵ(m)=g(n)g(m)
证毕。
四. 莫比乌斯反演
定义 I−1(I 的逆)是 μ。
那么若有 g=f∗I,得 f=g∗μ。
将其换一种写法,即得:
- 莫比乌斯反演:若 g(n)=∑d|nf(d),有 f(n)=∑d|ng(d)μ(nd)。反之亦然。
那么考虑如何求出 μ(n)。
由于 μ 是 I 的逆,而 I 是积性函数,所以 μ 也是积性函数。
显然得出 μ(pk)=⎧⎨⎩1k=0−1k=10k>1。
推广到一般数上,得:莫比乌斯函数 μ(n)=⎧⎨⎩1n=10∃i∈[1,k],ei>1(−1)kotherwise。
通过莫比乌斯反演有许多结论:
-
I(n)=∑d|nϵ(d)⇔ϵ(n)=∑d|nμ(d)
-
id(n)=∑d|nφ(d)⇔φ(n)=∑d|nμ(nd)d
-
φ(n)∗I(n)=id(n)
-
倍数莫比乌斯反演:若 g(n)=∑n|df(d),有 f(n)=∑n|dg(d)μ(dn)。
定义 (f⊕g)(n)=∑n|df(d)g(dn),易得 (f∗g)⊕h=f⊕(g⊕h)。
那么 f=(μ∗I)⊕f=μ⊕(I⊕g)=μ⊕g。
五. 数论分块
求 n∑i=1k%i。
显然 k%i=k−i⌊ki⌋。
考虑一个问题:求 n∑i=1f(i)⌊ni⌋。(f(i) 为某数论函数)
显然 ⌊ni⌋ 只有 2√n 种不同取值。
那么有 O(√n) 个块,对于每个块中所有数都相同。考虑对于同一块中两个数 ⌊ni⌋ 与 ⌊nj⌋,j 的最大值是 ⎢⎢
⎢
⎢
⎢⎣n⌊ni⌋⎥⎥
⎥
⎥
⎥⎦。(也就是块长。)
所以对于一个块知道左端点就可以求出右端点。
而对于块 [l,r] 贡献显然是 r∑i=lf(i)⌊nl⌋。
对于 f(i) 处理一个前缀和即可。
六. 莫反具体应用
求 1≤i,j≤n 且 gcd(i,j)∈P 的数对 (i,j) 个数。
n∑i=1n∑j=1[gcd(i,j)∈P]=∑k∈P⌊nk⌋∑i=1⌊nk⌋∑j=1ϵ(gcd(i,j))将 i,j 除以 gcd 后枚举gcd=∑k∈P⌊nk⌋∑i=1⌊nk⌋∑j=1∑d|gcd(i,j)μ(d)莫比乌斯反演=∑k∈P⌊nk⌋∑d=1μ(d)⌊ndk⌋∑i=1⌊ndk⌋∑j=11=∑k∈P⌊nk⌋∑d=1μ(d)⌊ndk⌋2=n∑t=1∑k|t,k∈Pμ(tk)⌊nt⌋2t 表示dk=n∑t=1⌊nt⌋2∑k|t,k∈Pμ(tk)
然后对于 ∑k|t,k∈Pμ(tk) 设其等于 f(t),那么 f(t) 可以在 O(nlnn) 内预处理。
而 $\displaystyle \sum_{t=1}n\left\lfloor\frac{n}{t}\right\rfloor2 $ 使用数论分块 O(√n)。
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e7+8;
int n,s[N],p[N],mu[N],ans,cnt;
bool vis[N];
inline void init(){
mu[1]=1;
for(int i=2;i<=n;i++){
if(!vis[i]){
p[++cnt]=i;
mu[i]=-1;
}
for(int j=1;j<=cnt,i*p[j]<=n;j++){
vis[i*p[j]]=1;
if(i%p[j]==0)break;
mu[i*p[j]]=-mu[i];
}
}
return;
}
signed main(){
scanf("%lld",&n);
init();
for(int i=1;i<=cnt;i++)for(int j=1;j*p[i]<=n;j++)s[j*p[i]]+=mu[j];
for(int i=2;i<=n;i++)s[i]+=s[i-1];
for(int i=1;i<=n;i++){
int l=i,r=(n/(n/l));
ans+=(s[r]-s[l-1])*(n/l)*(n/l);
i=r;
}
printf("%lld",ans);
return 0;
}
对于给出的 n 个询问,每次求有多少个数对 (x,y),满足 a≤x≤b,c≤y≤d,且 gcd(x,y)=k。
首先考虑一个弱化问题:将 a,c 变为 1。设此答案为 F(b,d)。
那么答案显然为 F(b,d)−F(b,c−1)−F(a−1,d)+F(a−1,c−1)。
那么问题转化为求 n∑i=1m∑j=1[gcd(i,j)=k]。
那么这个也就是类似上一题。
设 d(x) 为 x 的约数个数,给定 n,m,求
n∑i=1m∑j=1d(ij)
显然有个公式 d(ij)=∑x|i∑y|jϵ(gcd(x,y))。
所求即为 n∑i=1n∑j=1∑x|i∑y|jϵ(gcd(x,y))=n∑i=1m∑j=1⌊ni⌋⌊mj⌋ϵ(gcd(i,j))
。
那么设 f(x)=n∑i=1m∑j=1⌊ni⌋⌊mj⌋[gcd(i,j)=x],g(x)=∑x|df(d)。
答案即为 f(1)。
∴g(x)=n∑i=1m∑j=1⌊ni⌋⌊mj⌋∑x|d[gcd(i,j)=d]=n∑i=1m∑j=1⌊ni⌋⌊mj⌋[x∣gcd(i,j)]=⌊nx⌋∑i=1⌊mx⌋∑j=1⌊nix⌋⌊mjx⌋
根据倍数莫比乌斯反演,有 f(x)=∑x|dg(d)μ(dx)。
∴f(1)=∑dg(d)μ(d)
注意到当 d>n 时 g(d) 为 0,所以 d 枚举到 n。
f(1)=n∑d=1g(d)μ(d)
g(x) 使用数论分块做完。
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e5;
int T,n,m,s[N],p[N],mu[N],cnt,k,ans;
bool vis[N];
inline void init(){
mu[1]=1;
for(int i=2;i<N;i++){
if(!vis[i]){
p[++cnt]=i;
mu[i]=-1;
}
for(int j=1;j<=cnt,i*p[j]<N;j++){
vis[i*p[j]]=1;
if(i%p[j]==0)break;
mu[i*p[j]]=-mu[i];
}
}
for(int i=1;i<N;i++)mu[i]+=mu[i-1];
for(int i=1;i<N;i++){
int res=0;
for(int I=1,j;I<=i;I=j+1){
j=i/(i/I);
res+=(j-I+1)*(i/I);
}
s[i]=res;
}
return;
}
signed main(){
init();
scanf("%lld",&T);
while(T--){
scanf("%lld%lld",&n,&m);
if(n>m)swap(n,m);
for(int i=1;i<=n;i++){
int l=i,r=min(n/(n/i),m/(m/i));
ans+=(mu[r]-mu[l-1])*s[n/l]*s[m/l];
i=r;
}
printf("%lld\n",ans);
ans=0;
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
2022-01-17 【做题记录】Ynoi2018 天降之物
2022-01-17 【学术】连分数
2022-01-17 【做题记录】Ynoi2015 盼君勿忘
2022-01-17 【做题记录】BJOI2016 水晶
2022-01-17 【做题记录】P4965 薇尔莉特的打字机
2022-01-17 【做题记录】POI2011 Lightning Conductor
2022-01-17 【做题记录】CF961G Partitions