zoukankan      html  css  js  c++  java
  • 莫比乌斯反演+常见数论函数的性质+狄利克雷卷积+数论分块+杜教筛学习笔记

    一些约定

    1. 本文中所有未知数如没有特别说明,均为整数
    2. (gcd(a,b))表示a,b的最大公约数
    3. (a|b)表示a能整除b
    4. ([表达式])表示表达式成立的时候为1,不成立的时候为0.如([n=1])(n=1)的时候为1,否则为0
    5. (omega(n))表示n本质不同的质因子个数
    6. 在没有说明的情况下,所有除法都看做下取整

    预备知识

    积性函数

    首先,我们定义:定义域和值域都在整数集合中的函数称为数论函数(这个定义不严谨,但不影响等下的推导)

    定义:

    若数论函数(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))

    [mu(n)=egin{cases} 1,n=1 \ (-1)^k,n=prod_{i=1}^k p_k^{a_k},a_k=1 (即n的所有k个质因子指数均为1的时候) \ 0,otherwiseend{cases} ]

    其中第二种情况严谨的说,应该写成((-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))

    [varphi(n)=sum_{i=1}^n [gcd(i,n)=1] ]

    表示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...个数的方案数。

    [sum_{d|n} mu(d)=sum_{i=0}^k C_k^i (-1)^i=sum_{i=0}^k C_k^i (-1)^i 1^{k-i}=(-1+1)^k=0 ]

    倒数第二步用到了二项式定理.此时(varepsilon(n)=0),得证

    性质3:(varphi * I=id)

    证明:

    [id(n)=n=sum_{i|n}sum_{j=1}^n[gcd(j,n)=i] (把[1,n]的数按gcd分类) ]

    [=sum_{i|n}sum_{j=1}^{frac{n}{i}}[gcd(j,frac{n}{i})=1] (gcd(ka,kb)=kgcd(a,b)) ]

    [=sum_{i|n} varphi(frac{n}{i}) (欧拉函数的定义) ]

    [=sum_{i|n} varphi(i) ]

    [=(varphi*I)(n) ]

    性质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满足上面的条件,我们就可以大力反演了

    [f(x)= sum_{x|d} mu(d) F(lfloor frac{d}{x} floor) ]

    虽然这看起来是无限求和,但我们实际上求到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)

    [f(1)= sum_{1|d} mu(d) F(lfloor frac{d}{1} floor)= sum_{d=1}^{min(n,m)} mu(d) F(d)= sum_{d=1}^{min(n,m)} mu(d) lfloor frac{n}{d} floor lfloor frac{m}{d} floor ]

    数论分块

    数论分块其实和数据结构中的分块关系不大

    在莫比乌斯反演中,我们经常需要求解这种形式的式子(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)),这样就可以记忆化搜索了

    [H(n)=sum_{i=1}^n sum_{d|i} g(d) f(frac{i}{d}) ]

    改变求和顺序,先枚举d,$$原式=sum_{d=1}^n g(d) sum_{d|i} f(frac{i}{d})$$

    [=sum_{d=1}^n g(d)sum_{i=1}^{frac{n}{d}} f(i) ]

    [=sum_{d=1}^n g(d) F(frac{n}{d}) ]

    我们要求(F(n)),那么

    [g(1)F(n)=sum_{d=1}^n g(d) F(frac{n}{d})-sum_{d=2}^n g(d) F(frac{n}{d})=H(n)-sum_{d=2}^n g(d) F(frac{n}{d}) ]

    前半部分是狄利克雷卷积的前缀和的形式,后半部分可以数论分块然后记忆化搜索。如果(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]sum(杜教筛)

    [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;
    }
    

    习题(杜教筛)

    [BZOJ 3944]sum(杜教筛)

    [BZOJ 3930] [CQOI 2015]选数(莫比乌斯反演+杜教筛)

  • 相关阅读:
    第四章 数组和方法
    JAVA基础笔记
    ios navigationcontroller add multi navigationItem
    Objective-C Runtime能做什么?
    在Xcode中使用Git进行源码版本控制
    分析iOS Crash文件:符号化iOS Crash文件的3种方法
    Core Animation Layer(22)
    Touch Events and UIResponder(19)
    UIPopoverController and Modal View Controllers(13)
    Subclassing UITableViewCell(15)
  • 原文地址:https://www.cnblogs.com/birchtree/p/11436298.html
Copyright © 2011-2022 走看看