数论进阶
数论的一些反演
1.狄利克雷卷积
1.1积性函数
-
对于数论函数\(f\),对任意互质的正整数\(p,q\),满足\(f(pq)=f(p)f(q)\),则称\(f\)为积性函数
-
对于数论函数\(f\),对任意的正整数\(p,q\),满足\(f(pq)=f(p)f(q)\),则称\(f\)为完全积性函数
-
积性函数一定满足\(f(1)=1\)
-
对于任意大于\(1\)的正整数\(N\)和一个积性函数\(f\),假设\(N=p_1^{a_1}p_2^{a_2}...p_n^{a_n}\),那么\(f(N)=\prod_{i=1}^nf(p_i^{a_i})\),如果\(f\)为完全积性函数,则有\(f(N)=\prod_{i=1}^nf(p_i)^{a_i}\),由此可得凡是积性函数都可以用线性筛法求的
-
若\(f(x)\)和\(g(x)\)均为积性函数,则以下函数都是积性函数
\[h(x)=f(x^p)\\ h(x)=f^p(x)\\ h(x)=f(x)g(x)\\ h(x)=\sum_{d|x}f(d)g(\frac{x}{d}) \]
1.2常见积性函数
- \(\varphi(n)=n(1-\frac{1}{p_1})(1-\frac{1}{p_2})...(1-\frac{1}{p_m})\) 欧拉函数:\(1\)到\(n\)中与\(n\)互质的数的个数
- \(\sum_{d|n}\varphi(d)=n\)
- \(I(n)=1\) 不变函数
- \(id(n)=n\) 恒等函数
- \(\varepsilon(n)=[n==1]\)
- \(\sigma(n)=\sum_{d|n}d\) \(n\)的所有正因子之和
- \(d(n)=\tau(n)=\sum_{d|n}1\) \(n\)的所有正因子的个数
1.3狄利克雷卷积
定义:若\(f,g\)均为积性函数,那么\(f,g\)的狄利克雷卷积为\(f*g(n)=\sum_{d|n}f(d)g(\frac{n}{d})\)
性质
- 交换律:\(f*g(n)=g*f(n)\)
- 结合律:\(f*g*h(n)=f*(g*h)(n)\)
- 分配律:\(f*(g+h)(n)=f*g+f*h\)
- 单位元:\(f*\varepsilon=f\)
- \(f*g\)也为积性函数
1.4常见积性函数的卷积
- \(I*\varphi(n)=\sum_{d|n}1\times \varphi(n)=n=id(n)\)
- \(I*I(n)=\sum_{d|n}1=d(n)\)
- \(id*I(n)=\sum_{d|n}d=\sigma(n)\)
- \(\mu*I(n)=\sum_{d|n}\mu(d)\times1=[n==1]=\varepsilon(n)\)
- \(\mu*id(n)=\varphi(n)\)
- \(d*\mu(n)=I*I*\mu(n)=I*\varepsilon(n)=I\)
1.5狄利克雷前缀和和后缀积
- 定义
- \(g(n)=f*I(n)=\sum_{d|n}f(d)\),其中\(g,f\)都是积性函数,称\(g\)为\(f\)的狄利克雷前缀和
- \(g(n)=f*I(n)=\sum_{n|d}f(d)\),其中\(g,f\)都是积性函数,称\(g\)为\(f\)的狄利克雷后缀和
- 如果普通求解,时间复杂度是\(O(logn)\)的,但利用高维前缀和方法可以优化到\(O(loglogn)\)
以求狄利克雷前缀和为例,设\(n=\prod p_i^{\alpha_i}\),\(d=\prod p_i^{\beta_i}\),可以发现\(f(d)\)对\(g(n)\)有贡献当且仅到\(\forall i,\beta_i\lt \alpha_i\)。下标满足偏序关系,又是求和的形式,这不就是前缀和,所以这实际上是一个关于质因子分解后的指数的高维前缀和。
狄利克雷前缀和代码
for (int i = 1; i <= cnt && Prime[i] <= n; ++ i)
for (int j = 1; j * Prime[i] <= n; ++ j) f[j * Prime[i]] += f[j];
狄利克雷后缀和代码
for (int i = 1; i <= cnt && Prime[i] <= n; ++ i)
for (int j = n / Prime[i]; j; -- j) f[j] += f[j * Prime[i]];
2.莫比乌斯反演
2.1莫比乌斯函数
相关性质:
即\(\mu*I(n)=\sum_{d|n}\mu(d)\times1=[n==1]=\varepsilon(n)\)
于是有\([gcd(i,j)==1]=\sum_{d|gcd(i,j)}\mu(d)\)
2.2莫比乌斯反演
设有两个数论函数\(F(n),f(n)\),如果有\(F(n)=\sum_{d|n}f(d)\)
那么有
- \(f(n)=\sum_{d|n}\mu(d)F(\frac{n}{d})\),
- \(f(n)=\sum_{n|d}\mu(\frac{d}n)F(d)\)
证明:已知\(F=f*I\),证明\(f=F*\mu\)
2.3对莫比乌斯函数的一些理解
将一个数看做一个集合,它的每一个质因数为集合中的元素,莫比乌斯反演就是这样约数与倍数的加减容斥。
2.4常见反演技巧和公式
整除分块:对于任意一个\(i\),找到最大的\(j\),满足\(\lfloor \frac{i}{n}\rfloor=\lfloor \frac{j}{n}\rfloor\),则\(j=\lfloor \frac{n}{\lfloor \frac{i}{n}\rfloor}\rfloor\)
枚举因子、倍数等。
- \([gcd(i,j)==1]=\sum_{d|gcd(i,j)}\mu(d)\)
- \(\sum_{i=1}^N\sum_{j=1}^M[gcd(i,j==k)]=\sum_{i=1}^{\lfloor \frac{N}{k} \rfloor}\sum_{j=1}^{\lfloor \frac{M}{k} \rfloor}[gcd(i,j)==1]=\sum_{i=1}^{\lfloor \frac{N}{k} \rfloor}\sum_{j=1}^{\lfloor \frac{M}{k} \rfloor} \sum_{d|gcd(i,j)}\mu(d)=\sum_{d=1}^{min(\lfloor \frac{N}{k} \rfloor,\lfloor \frac{M}{k} \rfloor)}\mu(d)\lfloor \frac{N}{dk} \rfloor \lfloor \frac{M}{dk} \rfloor\)
3.杜教筛
- 作用:杜教筛被用来处理数论函数的前缀和问题。对于求解一个前缀和,杜教筛可以在低于线性时间的复杂度内求解(一般\(n\)很大时)
推导
- 问题:对于数论函数\(f\),要求计算\(S(n)=\sum_{i=1}^nf(i)\)
- 套路:构造\(S(n)\)关于\(S(\lfloor \frac{n}{i} \rfloor)\)的递推式
- 定理:对于一个数论函数\(g\),满足:\(\sum_{i=1}^n(g*f)(i)=\sum_{i=1}^n\sum_{d|i}g(d)f(\frac{i}{d})=\sum_{i=1}^ng(i)S(\lfloor \frac{n}{i} \rfloor)\)
常见积性函数的杜教筛推导
莫比乌斯函数\(\mu(n)\)
-
求\(S(n)=\sum_{i=1}^n\mu(i)\)
-
推导
令\(S(n)=\sum_{i=1}^n\mu(i)\),\(g(i)=I(i)=1\)
\[\sum_{i=1}^n(g*\mu)(i)=\sum_{i=1}^n\epsilon(i)=\sum_{i=1}^nI(i)S(\lfloor \frac{n}{i} \rfloor)=\sum_{i=1}^n1\times S(\lfloor \frac{n}{i} \rfloor)\\ S(n)=\sum_{i=1}^n\epsilon(i)-\sum_{i=2}^n1\times S(\lfloor \frac{n}{i} \rfloor)\\ S(n)=1-\sum_{i=2}^n1\times S(\lfloor \frac{n}{i} \rfloor) \]
欧拉函数\(\varphi(n)\)
-
求\(S(n)=\sum_{i=1}^n\varphi(i)\)
-
推导
\[S(n)=\sum_{i=1}^n\varphi(i)=\sum_{i=1}^n(\varphi *I)(i)=\sum_{i=1}^n1\times S(\lfloor \frac{n}{i} \rfloor)\\ \sum_{i=1}^n id(i)=\sum_{i=1}^n1\times S(\lfloor \frac{n}{i} \rfloor)\\ \frac{1}{2}n(n+1)=\sum_{i=1}^n1\times S(\lfloor \frac{n}{i} \rfloor)\\ S(n)=\frac{1}{2}n(n+1)-\sum_{i=2}^nS(\lfloor \frac{n}{i} \rfloor) \] -
代码:预处理出\(\varphi\)可以大幅度提高运行时间
#include <bits/stdc++.h> #define ll long long using namespace std; const int N=5e6+10; map<ll,ll>Sphi; int primes[N],st[N],cnt,phi[N]; void get_primes() { phi[1]=1; for(int i=2;i<=N-10;i++) { if(!st[i]) primes[++cnt]=i,phi[i]=i-1; for(int j=1;primes[j]*i<=N-10;j++) { st[primes[j]*i]=1; if(i%primes[j]==0) { phi[i*primes[j]]=phi[i]*primes[j]; break; } phi[i*primes[j]]=phi[i]*primes[j]; } } for(int i=1;i<=N-10;i++) phi[i]+=phi[i-1]; } ll S(ll n) { if(n<=N-10) return phi[n]; if(Sphi[n]) return Sphi[n]; ll res=n*(n+1)/2; for(ll l=2,r;l<=n;l=r+1) { r=n/(n/l); res-=(r-l+1)*S(n/l); } return Sphi[n]=res; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n; cin>>n; cout<<S((1LL<<31)-1)<<'\n'; }
4.Powerful Number筛
问题描述
- 存在一个函数\(g\)满足:
- \(g\)是积性函数
- \(g\)容易求前缀和
- 对于质数\(p\),\(g(p)=f(p)\)
假设现在要求极性函数\(f\)的前缀和\(F(n)=\sum_{i=1}^nf(i)\)
定义
- \(\text{powerful number}\):所有质因子\(p_i\)的幂次都大于\(1\)的数。即一个正整数\(n\)的算术分解中所有质因子的幂次大于\(1\),则称\(n\)是一个\(\text{PN}\)数
- 性质\(1\):所有\(\text{PN}\)数都可以表示成\(a^2b^3\)的形式:若\(\alpha_i\)是偶数,则把\(p_i\)并入\(a^2\)里面,若\(\alpha_i\)是奇数,则把\(p_i^{3}\)并入\(b^3\),再把\(p_i^{\alpha_i-3}\)并入\(a^2\)
- 性质\(2\):\(n\)以内的\(\text{PN}\)至多有\(O(\sqrt{n})\)个
PN筛
令\(g\)是满足问题描述里面要求的函数,\(f\)是要求的函数。令\(h\)是满足\(f=h*g\)的函数(这里是狄利克雷卷积),那么\(h(1)=1\),对于素数\(p\),\(f(p)=h(1)g(p)+h(p)g(1)=f(p)+h(p)\),可以退出\(h(p)=0\)。
又由于\(h\)是积性函数,所有所有非\(\text{PN}\)数的\(h\)取值均为\(0\),即\(h\)仅在\(\text{PN}\)数有取值
则
\(O(\sqrt{n})\)找出所有\(\text{PN}\),计算所有\(h\)的有效值。对于\(h\)有效值的计算,只需要计算出所有 \(h(p^c)\) 处的值,就可以根据 \(h\) 为积性函数推出\(h\) 的所有有效值
计算\(h(p^c)\)的方法
- 根据求出的关于\(p,c\)的公式直接计算
- 根据\(f=h*g\)移项计算
一般过程
- 构造\(g\)
- 根据\(f,g\)得到\(h\)
- 计算\(h(p^c)\)
- 搜索\(\text{PN}\)过程中累加答案
- 得到答案
参考链接
算法竞赛中的初等数论