一些约定
- 本文中所有未知数如没有特别说明,均为整数
- (gcd(a,b))表示a,b的最大公约数
- (a|b)表示a能整除b
- ([表达式])表示表达式成立的时候为1,不成立的时候为0.如([n=1])在(n=1)的时候为1,否则为0
- (omega(n))表示n本质不同的质因子个数
- 在没有说明的情况下,所有除法都看做下取整
预备知识
积性函数
首先,我们定义:定义域和值域都在整数集合中的函数称为数论函数(这个定义不严谨,但不影响等下的推导)
定义:
若数论函数(f)是积性函数,那么对于(forall gcd(a,b)=1,f(ab)=f(a)f(b))
若数论函数(f)是完全积性函数,那么对于(forall a,b in N,f(ab)=f(a)f(b))
常见的积性函数
1.莫比乌斯函数(mu(n))
其中第二种情况严谨的说,应该写成((-1)^{omega(n)})
证明:
我们分类讨论(mu)的符号
(1)当(mu(a)=1)时,(a=1),(mu(ab)=mu(b)=mu(a)mu(b))
(2)当(mu(a)=0)时,a有指数>1的质因子,乘上b后,ab一定有指数>1的质因子,因此(mu(ab)=0=mu(a)mu(b)),
(3)当(mu(a)=-1)时,(gcd(a,b)=1),则说明a,b没有公共质因子
(3.1)当(mu(b)=1)时,同(1)得证
(3.2)当(mu(b)=0)时,同(3)得证
(3.3)当(mu(b)=-1)时,a,b的质因子指数都为1,因为a,b没有公共质因子,因此ab的质因子指数也都为1,则(mu(ab)=(-1)^{omega(a)+omega(b)}=(-1)^{omega(a)}(-1)^{omega(b)}=mu(a)mu(b))
因此,(mu)是积性函数
性质1:若p是质数,(mu(p)=-1)
证明:满足第二种情况,(mu(p)=(-1)^1=-1)
性质2:若p是质数,(i in N)且(i)不整除p,(mu(pi)=-mu(i))
证明:
(1)当(mu(i)=0或1)的时候,显然得证
(2)当(mu(i)=-1)时i的质因数分解里显然没有p,那么pi的质因子个数比i多1个,会使得((-1)^k)的符号改变
根据性质1,2,我们可以类似线性筛素数的方法,写出线性筛莫比乌斯函数的代码
void sieve(int n){
mu[1]=1;
for(int i=2;i<=n;i++){
if(!vis[i]){
prime[++cnt]=i;
mu[i]=-1;//性质1
}
for(int j=1;j<=cnt&&i*prime[j]<=n;j++){
vis[i*prime[j]]=1;
if(i%prime[j]==0){//prime[j]|i,i*prime[j]中,质因子prime[j]的指数>1,mu值为0
mu[i*prime[j]]=0;
break;
}else mu[i*prime[j]]=-mu[i];//性质2
}
}
}
2.欧拉函数(varphi(n))
表示1~n中与n互质的数的个数
性质1:若p是质数,则(varphi(p)=p-1)
证明:显然1~p-1的数都与p互质
性质2:(forall)n>1,[1,n]中与n互质的数的和为(n imes varphi(n)/2)
证明:(gcd(n,x)=gcd(n,n-x)),所以与n互质的数x,n-x成对出现,平均值为(n/2),而互质的数又有(varphi(n))个
性质3:若n的质因数分解式为(prod_{i=1}^{k} p_i^{a_i}),则(varphi(n)=nprod_{i=1}^k(1-frac{1}{p_i}))
证明:
设p,q均为n的质因子,1~n中p的倍数有(frac{n}{p})个,q的倍数有(frac{n}{q})个,既是p的倍数也是q的倍数的数有(frac{n}{pq})个。根据容斥原理,既不是p的倍数也不是q的倍数的数有(n-frac{n}{p}-frac{n}{q}+frac{n}{pq}=n(1-frac{1}{p})(1-frac{1}{q}))个
两个数的结论显然可以推广到k个数,得证
由性质3,我们显然可以证明(varphi)是积性函数
性质4 : 若p是质数,当(p|i)时(varphi(pi)=varphi(i) imes p),当p不整除i的时候(varphi(pi)=varphi(i) imes (p-1))
证明:
当(p|i)时,pi包含的质因数和i包含的质因数相同,只是指数不同。根据性质3,(varphi(i)=iprod_{i=1}^k(1-frac{1}{p_i})),(varphi(pi)=piprod_{i=1}^k(1-frac{1}{p_i})).因此(varphi(pi)=varphi(i) imes p)
当p不整除i的时候,因为p是质数,所以p,i互质。因为欧拉函数是积性函数,(varphi(pi)=varphi(i) imes varphi(p)=varphi(i) imes (p-1))
类似筛莫比乌斯函数,我们可以写出线性筛欧拉函数的代码
void sieve(int n){
phi[1]=1;
for(int i=2;i<=n;i++){
if(!vis[i]){
prime[++cnt]=i;
phi[i]=i-1;//性质1
}
for(int j=1;j<=cnt&&i*prime[j]<=n;j++){
vis[i*prime[j]]=1;
if(i%prime[j]==0){//prime[j]|i
phi[i*prime[j]]=phi[i]*prime[j];
break;
}else phi[i*prime[j]]=phi[i]*(prime[j]-1);
}
}
}
3.约数个数函数(d(n))
若n的质因数分解式为(prod_{i=1}^k p_i^{a_i}),则(d(n)=prod_{i=1}^k(a_i+1))
4.约数和函数(sigma(n))
若n的质因数分解式为(prod_{i=1}^k p_i^{a_i}),则(sigma(n)=prod_{i=1}^k sum_{j=0}^{a_i}p_i^j))
常见的完全积性函数
1.常函数(I(n)=1)
2.恒等函数(id(n)=n)
3.单位函数(varepsilon(n)=[n=1])
狄利克雷卷积
定义:如果函数(F,f,g)满足$$F(n)=sum_{d|n} f(d)g(frac{n}{d})$$,则F是f和g的狄利克雷卷积,记作(F=(f*g)),或(F(n)=(f*g)(n))
由定义知,狄利克雷卷积满足交换律和结合律
性质1:(f*varepsilon=f)(任意函数卷积上单位函数都等于本身)
证明:
((f*varepsilon)(n)=sum_{d|n}f(d)varepsilon(frac{n}{d}))
显然只有(frac{n}{d}=1)的时候乘积才不为0,((f*varepsilon)(n)=f(n)varepsilon(1)=f(n))
性质2:(mu *I=varepsilon)
证明:
当(n=1)时,(mu(n)=varepsilon(n)=1)
当(n eq 1)时,我们要求证(varepsilon(n)=sum_{d|n} mu(d))
设n的质因数分解式为(prod_{i=1}^k p_i^{a_i}),则d是在这里面选择一些质因子乘起来得到的。只有选的质因子指数为1的时候才会对答案有1或-1的贡献,取决于。那么问题就转换成在k个质因子中选0,1,2,3...个数的方案数。
倒数第二步用到了二项式定理.此时(varepsilon(n)=0),得证
性质3:(varphi * I=id)
证明:
性质4:(mu*id=varphi)
证明:
由性质2知(mu * I=varepsilon)
由性质3知(id=varphi *I)
那么(id * varepsilon=id=varphi * I)
代入(mu * I=varepsilon),(id * mu * I=varphi *I)
约掉(I),得(mu*id=varphi)
性质5:(d=I*I)
证明:(d(n)=sum_{d|n}1 imes 1),n的约数个数就是整除n的数的个数,显然得证
性质6: (sigma=I*id)
证明:(sigma(n)=sum_{d|n}d=sum_{d|n}1 imes id(d)),显然得证
我们再来总结一下比较重要的几条性质,因为在莫比乌斯反演里会用到:
(mu *I=varepsilon)
(varphi * I=id)
(f * varepsilon =f)
莫比乌斯反演
莫比乌斯反演是一种简化计算的方法
比如,我们可以用函数f表示F,比如(F(n)=sum_{d|n}f(d))那么能不能用F来表示f呢?
莫比乌斯反演的约数形式
定理:若(F(n)=sum_{d|n}f(d)),则(f(n)=sum_{d|n}F(d) mu(frac{n}{d}))
这就是莫比乌斯反演的约数形式(第一种形式),观察式子得到,我们用(F,mu)来表示了(f)
如果我们要求f,但f比较难求解。而f求和可以得到一个函数F,F很好求,那么就可以用莫比乌斯反演求解出f.因此用莫比乌斯反演做题的时候,重点是找出好求解的函数F,来优化f的求解过程.
关于这个定理的证明,可以不依靠狄利克雷卷积直接证明,但式子较繁琐。这里用卷积证明:
把已知条件写成卷积形式,(F=f*I)
两边卷积上(mu),得(F*mu=f*I*mu)
由(mu *I=varepsilon),得(F*mu=f *varepsilon=f)
再写成求和形式,(f(n)=sum_{d|n}F(d) mu(frac{n}{d}))
莫比乌斯反演的倍数形式
定理,若(F(n)=sum_{n|d}f(d)),则(f(n)=sum_{n|d}F(d) mu(frac{d}{n}))
这就是莫比乌斯反演的倍数形式(第二种形式)。观察式子得到,这是一个无限求和,但往往题目中其实只需要求到一个上界。
这种形式的证明见:https://oi-wiki.org/math/mobius/
为了加深理解,可以看一道例题:[BZOJ 2301] [HAOI 2011] Problem b (莫比乌斯反演)(有证明)
[BZOJ 2301] 求(sum _{i=a}^bsum _{j=c}^d[gcd(i,j)=k]) (a,b,c,d,kle 5 imes 10^4)
(O(n^2))暴力显然是不可行的,我们考虑优化。
首先易得(k imes gcd(i,j)=gcd(ki,kj)),那么我们可以把a,b,c,d都除上k,问题就变成了(sum _{i=a/k}^{b/k}sum _{j=c/k}^{d/k}[gcd(i,j)=1])(之后的除法若未说明,均为下去整)。差分一下,我们只要求出(sum_{i=1}^n sum_{j=1}^m [gcd(i,j)=1]),然后二维前缀和相减一下就可以了
既然要用到莫比乌斯反演,我们首先就要找到合适的F和f
设
(f(x)=sum_{i=1}^n sum_{i=1}^m [gcd(i,j)=x]),(gcd为x的(x,y)的对数)
(F(x)= sum_{i=1}^n sum_{i=1}^m [x |gcd(i,j)]), (gcd为x或x的倍数的(x,y)的对数)
显然$F(x)=sum f(i) $(i是x的倍数),因为gcd(x,i)能整除x,那i一定能整除x。
既然F,f满足上面的条件,我们就可以大力反演了
虽然这看起来是无限求和,但我们实际上求到min(n,m)就可以了,因为gcd(i,j)(i<n,j<m)不可能超过i,j中的最小值。
注意到(F(x)= sum_{i=1}^n sum_{i=1}^m [x |gcd(i,j)]= lfloor frac{n}{x} floor lfloor frac{m}{x} floor),因为gcd(i,j)为x的倍数,那么i,j一定都被x整除,显然1~n中x的倍数有n/x个
我们求的答案实际上是f(1)
数论分块
数论分块其实和数据结构中的分块关系不大
在莫比乌斯反演中,我们经常需要求解这种形式的式子(sum_{i=1}^n f(i) lfloor frac{n}{i} floor)
暴力枚举求解i的复杂度仍然较高
观察到d比较大的时候n/d的值变化不大,如n=6时n/4=n/5=n/6.
因此我们可以找出所有下取整值相同的区间[l,r],再用(sum lfloorfrac{n}{l} floor sum_{i=l}^r f(i))就可以求出答案,求和部分可以前缀和预处理。对于一个块,假设它的起始位置的下标为l,那么可以得到的是,它的结束位置的下标为n/(n/l)
如果我们预处理出f的前缀和,那么数论分块的复杂度是(O(sqrt{n}))的。
下面的代码求解了(sum_{d=1}^n mu(d) lfloor frac{n}{d} floor lfloor frac{m}{d} floor)
long long ans=0;
int l,r;
for(l=1;l<=m;l=r+1){
r=min(n/(n/l),m/(m/l));
ans+=(sum_mu[r]-sum_mu[l-1])*(n/l)*(m/l);//sum_mu为mu的前缀和
}
习题(狄利克雷卷积+莫比乌斯反演)
[BZOJ 2301] [HAOI 2011] Problem b (莫比乌斯反演)(有证明)
[BZOI 3994] [SDOI2015]约数个数和(莫比乌斯反演+数论分块)
[BZOJ 2820] YY的gcd(莫比乌斯反演+数论分块)
[BZOJ 2154]Crash的数字表格(莫比乌斯反演+数论分块)
杜教筛
在莫比乌斯反演中,我们常常要求一个积性函数f的前缀和。它通过狄利克雷卷积的转化,最终利用预处理和记忆化搜索的思想来降低复杂度
设(h=f*g),(F,G,H)为她们的前缀和。
我们想办法用(F(frac{n}{d}),g,H)等表示出(F(n)),这样就可以记忆化搜索了
改变求和顺序,先枚举d,$$原式=sum_{d=1}^n g(d) sum_{d|i} f(frac{i}{d})$$
我们要求(F(n)),那么
前半部分是狄利克雷卷积的前缀和的形式,后半部分可以数论分块然后记忆化搜索。如果(h(n)=f*g)的前缀和可以在(O(1))求(一般如(h(n)=1,h(n)=n))等,就可以直接记忆化了
但是这样一直往下记忆化,时间复杂度还是(O(n))的,
这时容易想到了线性筛法,假如我们把一部分的f筛出来,然后求出F,那么递归到一定范围时就可以O(1)返回了
可(wo)以(ye)证(bu)明(hui),当我们筛出(O(n^{frac{2}{3}}))个f的时候,总时间复杂度是(O(n^{frac{2}{3}}))。这样,很多求和问题的范围就可以做到(10^{12})左右
[BZOJ 3944] 求(mu)和(varphi)的前缀和,
套路公式:
我们要求(f)的前缀和,构造两个函数(g,h)满足(h=f*g), (F,G,H)为它们的前缀和
[g(1)F(n)=H(n)-sum_{d=2}^n g(d) F(frac{n}{d}) ]
如果(f=mu),注意到(mu*I=varepsilon),那么(g(n)=I(n)=1,h(n)=varepsilon(n),H(n)=varepsilon(1)=1)
代入得(F(n)=1-sum_{d=2}^n F(frac{n}{d}))
如果(f=varphi),注意到(varphi * I=id),那么(g(n)=I(n)=1,h(n)=n,H(n)=sum_{i=1}^ni=frac{n(n+1)}{2})
代入得(F(n)=frac{n(n+1)}{2}-sum_{d=2}^n F(frac{n}{d}))
然后记忆化搜索,用map记录答案,求和的部分用数论分块。注意为了方便理解把两个函数的求和分开,如果要通过本题需要把两个函数的求和合起来写,否则常数较大。详见上方超链接
ll sum_mu[maxn+5];//sum_mu为线性筛出的mu前缀和,线性筛部分略
ll sum_phi[maxn+5];//sum_phi为线性筛出的phi前缀和
map<ll,ll>ans_mu;
map<ll,ll>ans_phi;
ll sieve_mu(ll n){//orz dujiao
if(n<=maxn) return sum_mu[n];
if(ans_mu.find(n)!=ans_mu.end()) return ans_mu[n];
ll ans=1;
for(ll l=2,r;l<=n;l=r+1){
r=n/(n/l);
ans-=(r-l+1)*sieve_mu(n/l);
}
ans_mu[n]=ans;
return ans;
}
ll sieve_phi(ll n){
if(n<=maxn) return sum_phi[n];
if(ans_phi.find(n)!=ans_phi.end()) return ans_phi[n];
ll ans=n*(n+1)/2;
for(ll l=2,r;l<=n;l=r+1){
r=n/(n/l);
ans-=(r-l+1)*sieve_phi(n/l);
}
ans_phi[n]=ans;
return ans;
}