欧拉筛法&欧拉函数
1.欧拉筛法
1. 原理
通过枚举一个1~n的数和已筛出的质数,他们的积为一个合数
2. 代码实现
for(int i=2;i<=n;i++){
if(!vis[i]) prime[++tot]=i;
for(int j=1;j<=tot;j++){
if(1ll*i*prime[j]>n) break;//大于时退出
vis[i*prime[j]]=1;//质数的倍数不是质数
if(i%prime[j]==0) break; //!!!重要优化
//令i=k*prime[j] 则 i*prime[j+x] 在i枚举到 k*prime[j+x]时
//即会被筛去,为了防止重复筛除, break 掉;
}
}
2. 欧拉函数
1. 理论知识
1. 定义: 欧拉函数 (varphi(x)) 为小于等于(x)且与(x)互质的数的个数
2. 重要性质
○1.(varphi(p)=p-1) ((p)是质数).
○2.(varphi(x))为积性函数 即 (varphi (p*q)= varphi (p)*varphi (q)) 其中 p,q互质 .
○3.(varphi (p^k)=(p-1) p^{k-1}) (p是质数).
○4.当p为质数且(p|x)时,(varphi (x*p)=varphi (x)*p)
○5.设n是一个正整数,(sum_{d|n}varphi(d)=n)
○6.设(1<=k<=n),那么有(sum_{(k,n)=1}k=frac12nvarphi(n))
○7.若a与n互质,那么若(a^nequiv b (mod;p))则(a^{n;mod;varphi(p)}equiv b(mod;p))(由欧拉定理易得)
○8.若(a^nequiv b (mod;p))则(a^{n;mod;varphi(p)+varphi(p)} equiv b(mod;p))扩展欧拉定理(不要求a和p互质)
性质3的证明:
(ecause p^k) 仅含有 (p) 这一个质因子故小于 (p^k)的不与之互质的数仅有(p)的倍数,共有(dfrac{p^k}{p}=p^{k-1})个
即$varphi (pk)=pk-p{k-1}=p{k-1}*(p-1) $即证
性质4的证明:
(ecause p|x)令P为x的质因子集合((1-1/P)=(1-1/p_1)*...*(1-1/p_n))
( herefore varphi(x)=x*(1-1/P) ,varphi(p)=p-1)
( herefore varphi (x*p)=(x*p)(1-1/P)) (引入p后质因子集合不变 (ecause p)是(x)的质因子)
( herefore varphi(x*p)=x*(1-1/P)*p= varphi(x)*p,) 即证
2. 求法 :
通项公式:$$varphi(x)=x*prod(1-frac1{p_i})其中p为x的质因子$$
证明如下:
预备知识:
1. (varphi(p)=p-1) ( $ p $ 是质数 )
2. 唯一分解定理: (x=(p_1^{k_1} *p_2^{k_2}dots*p_n^{k_n})) 其中(p)为(x)的质因子
3. (varphi(x))为积性函数 即 (varphi(p*q)=varphi(p)*varphi(q)) 其中 p,q互质 .
4. (varphi(p^k)=(p-1)×(p^{k-1}))
证明:
(varphi(x) = varphi (p_1^{k_1}*p_2^{k_2} dots *p_n^{k_n}))其中(p)为(x)的质因子
(ecause x)的质因子的任何次方都互质
( herefore varphi(x)=varphi(p_1^{k_1}) * varphi(p_2^{k_2})*dots*varphi(p_n^{k_n}))
而(varphi(p^k)=(p-1)×(p^{k-1}))
( herefore varphi(x)=(p_1-1) ×(p_2-1)*....*(p_n-1)(p_1^{k_1-1} *p_2^{k_2-1}dots*p_n^{k_n-1}))
前面各项每项提出一个(p_i)乘到后面去即得 (varphi(x)=x*prod(1-dfrac{1}{p_i}))
4. 公式法和线性递推法求解欧拉函数
- (O(sqrt{n})) 公式法
inline int phi(int x)
{
if(x==1) return 1;
int res=x;
for(register int i=2;i<=sqrt(x);i++){
if(x%i==0){
res-=res/i;
while(x%i==0) x/=i;
}
}
if(x!=1) res-=res/x;//最后一个也要算;
return res;
}
2.(O(n)) 递推法
for(int i=2;i<=n;i++){
if(!vis[i]) {prime[++tot]=i;phi[i]=i-1;}
for(int j=1;j<=tot;j++){
if(1ll*i*prime[j]>n) break;
vis[i*prime[j]]=1;
if(i%prime[j]==0) {
phi[i*prime[j]]=phi[i]*prime[j];
//当 prime[j]是i的约数时,phi[i*prime[j]]=phi[i]*prime[j];
break;
}
phi[i*prime[j]]=phi[i]*(phi[prime[j]]);
//否则,phi[i*prime[j]]=phi[i]*phi[j] =phi[i]*(prime[j]-1);
}
}
2. 欧拉函数的一些应用
例1. 作为体育委员,C君负责这次运动会仪仗队的训练。仪仗队是由学生组成的N * N的方阵,为了保证队伍在行进中整齐划一,C君会跟在仪仗队的左后方,根据其视线所及的学生人数来判断队伍是否整齐(如下图)。 现在,C君希望你告诉他队伍整齐时能看到的学生人数。luogu-P2158 [SDOI2008]仪仗队
解析:
观察发现,以观察点的右上为第1行第1列,则能被看到的点(x,y)在第x行第y列,必须满足 gcd(x,y)==1才能被看到,由图的对称性故最后答案应为:
$$2×(varphi(2)+varphi(3)+....+varphi(N-1))+3$$
最后加三是对角线、左、右能看到的人。
例2.给定一个整数N,你需要求出(sum gcd(i, N)(1<=i <=N)) luogu-P2303 Longge的问题
解析: 令t(x)为 gcd(i,N) 为 x 的个数。∴ t(1)=Φ(N) ;
$$t(x)=sum (gcd(i,N)x)=sum (gcd(i/x,n/x)1)=sum varphi(n/x)$$
故当x是n的因数时求出Φ(x/n)即可
例3. 题意:输入 N 和 M (2<=N<=1000000000, 1<=M<=N), 找出所有的X满足1<=X<=N 且 gcd(X,N)>=M.HDU-2588 GCD
解析:
1.首先若m==1,则答案为N
2.m≠1时,初步想法,将N进行质因数分解,则答案为其质因数的组合的积中大于m的组合个数,但实现起来不现实。
不妨设(gcd(X,N)=Y >=M)
则: (令X=K*Y,其中一定有gcd(K,N)=1 且 Y|N,即Y是N的约数)
于是有以下做法:先求出N的所有约数Y,(varphi(N/Y))之和(即符合条件的K的个数)
即为答案
为什么是(varphi(N/Y))呢? 因为这样才能保证 (K*Y<=N)