【数论】浅谈线性筛

前置知识

线性筛质数
积性函数定义:若一个定义域在正整数上的函数 f ( x ) f(x) f(x) 满足 ∀ x , y ∈ N + 且 gcd ⁡ ( x , y ) = 1 , f ( x y ) = f ( x ) f ( y ) \forall x,y\in N_+\text{且} \gcd(x,y)=1,f(xy)=f(x)f(y) x,yN+gcd(x,y)=1,f(xy)=f(x)f(y)
凡是积性函数,都可以用线性筛。

剖析线性筛质数
回顾整个算法,我们发现每个正整数都只会被它的最小质因子筛掉,故整个算法的时间复杂度为 O ( n ) O(n) O(n)
这里给出参考代码:

void ola(int x){
	pr[1]=1;
	for(int i=1;i<=x;i++){
		if(!pr[i])
			prv[++cnt]=i;
		for(int j=1;j<=cnt&&i*prv[j]<=x;j++){
			pr[i*prv[j]]=1;
			if(i%prv[j]==0)
				break;
		}
	}
}

于是我们就可以以此为基础筛一些积性函数了。

欧拉函数

定义
欧拉函数 φ ( n ) \varphi(n) φ(n) 表示小于等于 n n n,且与 n n n 互质的正整数的个数。特别的, φ ( 1 ) = 1 \varphi(1)=1 φ(1)=1

求单个欧拉函数
n = ∏ i = 1 q p i x i n=\prod_{i=1}^qp_i^{x_i} n=i=1qpixi(质因数分解,如无特殊说明,下文此形式均为质因数分解),集合 A i A_i Ai 表示不大于 n n n 且是 p i p_i pi 的倍数的自然数的集合。

所有 ∣ A i ∣ = n p i |A_i|=\frac{n}{p_i} Ai=pin
因为 gcd ⁡ ( p i , p j ) = 1 ( i ≠ j ) \gcd(p_i,p_j)=1(i\ne j) gcd(pi,pj)=1(i=j)
所以 ∣ A i ∩ A j ∣ = n p i p j |A_i\cap A_j|=\frac{n}{p_ip_j} AiAj=pipjn
再结合容斥:
在这里插入图片描述
参考代码:

int getphi(int x){
	int res=x;
	for(int i=2;i*i<=x;i++){
		if(x%i==0)
			res=res*(i-1)/i;
		while(x%i==0)
			x/=i;
	}
	if(x>1)
		res=res*(x-1)/x;
	return res;
}

欧拉函数是积性函数
证明:
φ ( n ) φ ( m ) = n ∏ i = 1 x ( 1 − 1 p i ) m ∏ i = x + 1 x + y ( 1 − 1 p i ) = φ ( n m ) \varphi(n)\varphi(m)=n\prod_{i=1}^x(1-\frac{1}{p_i})m\prod_{i=x+1}^{x+y}(1-\frac{1}{p_i})=\varphi(nm) φ(n)φ(m)=ni=1x(1pi1)mi=x+1x+y(1pi1)=φ(nm)
由于 gcd ⁡ ( n , m ) = 1 \gcd(n,m)=1 gcd(n,m)=1,所以 n , m n,m n,m的每个质因子必不相同,所以得证。

性质

  1. n n n 是质数, φ ( n ) = n − 1 \varphi(n)=n-1 φ(n)=n1
  2. p p p 为质数,且 n = p k n=p^k n=pk,则 φ ( n ) = ( p − 1 ) p k − 1 \varphi(n)=(p-1)p^{k-1} φ(n)=(p1)pk1
  3. q q q 为质数,且 ∃ k ∈ N + \exists k\in N_+ kN+ 使得 n = q k n=qk n=qk,则 φ ( n q ) = q φ ( n ) \varphi(nq)=q\varphi(n) φ(nq)=(n)
  4. q q q 为质数,且 ∀ k ∈ N + \forall k\in N_+ kN+ n ≠ q k n\ne qk n=qk,则 φ ( n q ) = ( q − 1 ) φ ( n ) \varphi(nq)=(q-1)\varphi(n) φ(nq)=(q1)φ(n)
  5. n = ∑ d ∣ n φ ( d ) n=\sum_{d|n}\varphi(d) n=dnφ(d)
  6. φ ( a b ) = φ ( a ) φ ( b ) d φ ( d ) \varphi(ab)=\varphi(a)\varphi(b)\frac{d}{\varphi(d)} φ(ab)=φ(a)φ(b)φ(d)d,其中 d = gcd ⁡ ( a , b ) d=\gcd(a,b) d=gcd(a,b)

证明

  1. 不证
  2. φ ( n ) = n ( 1 − 1 p ) = p k p − 1 p = ( p − 1 ) p k − 1 \varphi(n)=n(1-\frac{1}{p})=p^k\frac{p-1}{p}=(p-1)p^{k-1} φ(n)=n(1p1)=pkpp1=(p1)pk1
  3. φ ( n q ) = n q ∏ i = 1 x ( 1 − 1 p i ) = q n ∏ i = 1 x ( 1 − 1 p i ) = q φ ( n ) \varphi(nq)=nq\prod_{i=1}^x(1-\frac{1}{p_i})=qn\prod_{i=1}^x(1-\frac{1}{p_i})=q\varphi(n) φ(nq)=nqi=1x(1pi1)=qni=1x(1pi1)=(n)
  4. n = ∏ i = 1 y p i x i , φ ( n q ) = n q ( 1 − 1 q ) ∏ i = 1 y ( 1 − 1 p i ) = q q − 1 q [ n ∏ i = 1 y ( 1 − 1 p i ) ] = ( q − 1 ) φ ( n ) n=\prod_{i=1}^yp_i^{x_i},\varphi(nq)=nq(1-\frac{1}{q})\prod_{i=1}^y(1-\frac{1}{p_i})=q\frac{q-1}{q}[n\prod_{i=1}^y(1-\frac{1}{p_i})]=(q-1)\varphi(n) n=i=1ypixi,φ(nq)=nq(1q1)i=1y(1pi1)=qqq1[ni=1y(1pi1)]=(q1)φ(n)
  5. 如图
    在这里插入图片描述
    理性理解: n = ∑ d ∣ n ∑ i = 1 n [ gcd ⁡ ( i , n ) = d ] = ∑ d ∣ n ∑ i = 1 n d [ gcd ⁡ ( i , n d ) = 1 ] = ∑ d ∣ n φ ( n d ) = ∑ d ∣ n φ ( d ) \large{n=\sum_{d|n}\sum_{i=1}^n[\gcd(i,n)=d]=\sum_{d|n}\sum_{i=1}^\frac{n}{d}[\gcd(i,\frac{n}{d})=1]=\sum_{d|n}\varphi(\frac{n}d{})=\sum_{d|n}\varphi(d)} n=dni=1n[gcd(i,n)=d]=dni=1dn[gcd(i,dn)=1]=dnφ(dn)=dnφ(d)

d = ∏ i = 1 q 1 p 1 i x 1 i , a = ∏ i = 1 q 2 p 2 i x 2 i , b = ∏ i = 1 q 3 p 3 i x 3 i φ ( a b ) = a b ∏ i = 1 q 2 ( 1 − 1 p 2 i ) ∏ i = 1 q 3 ( 1 − 1 p 3 i ) ∏ i = 1 q 1 ( 1 − 1 p 1 i ) = φ ( a ) φ ( b ) 1 d φ ( d ) = φ ( a ) φ ( b ) d φ ( d ) \large{d=\prod_{i=1}^{q_1}{p_{1i}}^{x_{1i}},a=\prod_{i=1}^{q_2}{p_{2i}}^{x_{2i}},b=\prod_{i=1}^{q_3}{p_{3i}}^{x_{3i}}}\\\varphi(ab)=\frac{ab\prod_{i=1}^{q_2}(1-\frac{1}{p_{2i}})\prod_{i=1}^{q_3}(1-\frac{1}{p_{3i}})}{\prod_{i=1}^{q_1}(1-\frac{1}{p_{1i}})}=\frac{\varphi(a)\varphi(b)}{\frac{1}{d}\varphi(d)}=\varphi(a)\varphi(b)\frac{d}{\varphi(d)} d=i=1q1p1ix1i,a=i=1q2p2ix2i,b=i=1q3p3ix3iφ(ab)=i=1q1(1p1i1)abi=1q2(1p2i1)i=1q3(1p3i1)=d1φ(d)φ(a)φ(b)=φ(a)φ(b)φ(d)d

线性筛欧拉函数

回顾性质 1 , 3 , 4 1,3,4 1,3,4,也就是我们筛欧拉函数的基础了,即我们在筛质数的时候顺便把欧拉函数也给筛出来。
参考代码:

void ola(int x){
	pr[1]=phi[1]=1;
	for(int i=1;i<=x;i++){
		if(!pr[i])
			prv[++cnt]=i,phi[i]=i-1;
		for(int j=1;j<=cnt&&i*prv[j]<=x;j++){
			int u=i*prv[j];
			pr[u]=1;
			if(i%prv[j]==0){
				phi[u]=phi[i]*prv[j];
				break;
			}
			else{
				phi[u]=phi[i]*(prv[j]-1);
			}
		}
	}
}

d ( x ) d(x) d(x)

d ( x ) d(x) d(x) 表示 x x x 的约数的个数。

  1. d ( x ) d(x) d(x) 是积性函数。
    证明:
    A = ∏ i = 1 n p i x i , B = ∏ i = 1 m q i y i , n = A B , g c d ( A , B ) = 1 d ( A ) = ∏ i = 1 n ∑ j = 0 x i p i j , d ( B ) = ∏ i = 1 m ∑ j = 0 y i q i j ∵ gcd ⁡ ( A , B ) = 1 , ∴ n = ∏ i = 1 n p i x i ∏ i = 1 m q i y i ∴ d ( n ) = ∏ i = 1 n ∑ j = 0 x i p i j ∏ i = 1 m ∑ j = 0 y i q i j ∴ d ( n ) = d ( A ) d ( B ) \large{A=\prod_{i=1}^np_i^{x_i},B=\prod_{i=1}^mq_i^{y_i},n=AB,gcd(A,B)=1}\\ d(A)=\prod_{i=1}^n\sum_{j=0}^{x_i}p_i^{j},d(B)=\prod_{i=1}^m\sum_{j=0}^{y_i}q_i^{j}\\ \because \gcd(A,B)=1,\therefore n=\prod_{i=1}^np_i^{x_i}\prod_{i=1}^mq_i^{y_i}\\ \therefore d(n)=\prod_{i=1}^n\sum_{j=0}^{x_i}p_i^{j}\prod_{i=1}^m\sum_{j=0}^{y_i}q_i^{j}\\ \therefore d(n)=d(A)d(B) A=i=1npixi,B=i=1mqiyi,n=AB,gcd(A,B)=1d(A)=i=1nj=0xipij,d(B)=i=1mj=0yiqijgcd(A,B)=1,n=i=1npixii=1mqiyid(n)=i=1nj=0xipiji=1mj=0yiqijd(n)=d(A)d(B)

  2. 线性筛 d ( x ) d(x) d(x)
    在这里插入图片描述

  • 参考代码:
void ola(int x){
	pr[1]=d[1]=1;
	for(int i=1;i<=x;i++){
		if(!pr[i])
			prv[++cnt]=i,d[i]=2,mx[i]=i,mi[i]=1;
		for(int j=1;j<=cnt&&i*prv[j]<=x;j++){
			int u=i*prv[j];
			pr[u]=1;
			if(i%prv[j]==0){
				mi[u]=mi[i]+1;
				mx[u]=mx[i]*prv[j];
				d[u]=(mx[u]==u?mi[u]+1:d[mx[u]]*d[u/mx[u]]);
				break;
			}
			else{
				mi[u]=1;
				mx[u]=prv[j];
				d[u]=d[mx[u]]*d[u/mx[u]];
			}
		}
	}
}
  • 19
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值