Label
欧拉函数(此处将此题作为欧拉函数模板套路题分析)
Description
https://www.luogu.com.cn/problem/P2158
Solution
本题思路
我们首先转化题意:假设当前C君站在(0,0)(0,0)(0,0)处,右上角坐标为(n−1,n−1)(n-1,n-1)(n−1,n−1),那么:设一名站在坐标(x,y)(x,y)(x,y)处的学生:
若该学生不能被看见,当且仅当∃d∈N(d∣x∧d∣y)\exist d\in N(d|x\land d|y)∃d∈N(d∣x∧d∣y)
进一步转化条件:如果该学生能被看见,则说明┐∃d∈N(d∣x∧d∣y)\urcorner\exist d\in N(d|x\land d|y)┐∃d∈N(d∣x∧d∣y),那么***从质因子分解的角度考虑***,此时x,yx,yx,y不存在相同的质因子,进而说明x,yx,yx,y互质。
所以,站在坐标(x,y)(x,y)(x,y)处的学生能被看见等价于gcd(x,y)=1gcd(x,y)=1gcd(x,y)=1(x,yx,yx,y互质)
考虑欧拉函数的定义:φ(n)=∑i=1n[gcd(i,n)==1]\varphi(n)=\sum_{i=1}^{n}[gcd(i,n)==1]φ(n)=∑i=1n[gcd(i,n)==1],即:φ(n)\varphi(n)φ(n)表示[1,n][1,n][1,n]内与nnn互质的数的个数。
那么,对于此题,答案即为3+2∑i=2nφ(i)3+2\sum_{i=2}^{n}\varphi(i)3+2∑i=2nφ(i)。(1、考虑(x,y),(y,x)(x,y),(y,x)(x,y),(y,x)同时合法/不合法;2、(0,1),(1,0),(1,1)(0,1),(1,0),(1,1)(0,1),(1,0),(1,1)处的学生一定可以被看见,(0,x),(x,0)(x>1)(0,x),(x,0)(x>1)(0,x),(x,0)(x>1)的学生一定不能被看见)。
总结:涉及到gcd(x,y)gcd(x,y)gcd(x,y)取值可能为1的问题,往往需要用到欧拉函数。
求φ(1)∼φ(n)\varphi(1)\sim\varphi(n)φ(1)∼φ(n)的方法
O(nn)O(n\sqrt n)O(nn)求法
由于φ(n)=n∏pp∣np−1p\varphi(n)=n\prod_{p}^{p|n}\frac{p-1}{p}φ(n)=np∏p∣npp−1,故我们可以对1∼n1\sim n1∼n内的每个数进行质因子分解即可。
int Phi(int x)//求phi(x)一般用利用容斥原理推出的公式,O(sqrt(n))
{
ri phix=x;
for(ri i=2;i*i<=x;++i)
if(x%i==0)
{
phix=phix/i*(i-1);
while(x%i==0) x/=i;//由于i|x,故不会出现精度问题
}
if(x>1) phix=phix/x*(x-1);//注意可能大于sqrt(x)的质因子
return phix;
}
O(n)O(n)O(n)求法
一般的O(n)O(n)O(n)做法利用了线性筛(欧拉筛)法的良好性质。
进行筛法的过程中,对于素数nnn,直接令φ(n)=n−1\varphi(n)=n-1φ(n)=n−1即可。关键在于怎么把非素数的欧拉函数表示出来。
由于线性筛具有“每一个数只会被其最小的质因子筛去”的优秀性质,故我们可以考虑合数n=p×kn=p\times kn=p×k在被它的最小质因子ppp筛去时,利用φ(p)\varphi(p)φ(p)与φ(k)\varphi(k)φ(k)的值来求φ(n)\varphi(n)φ(n)(此处线性筛外层循环枚举待筛数的最大因子的筛取性质证得:若kkk为合数,当线性筛外层循环循环至kkk时,kkk是否为素数及φ(k)\varphi(k)φ(k)已被求出)。
1、p∣kp|kp∣k
此时说明nnn只含一个值为ppp的素因子(不是只含一个素因子),由于欧拉函数满足积性函数的性质,故当gcd(k,p)=1gcd(k,p)=1gcd(k,p)=1时,φ(n)=φ(pk)=φ(p)φ(k)=(p−1)k\varphi(n)=\varphi(pk)=\varphi(p)\varphi(k)=(p-1)kφ(n)=φ(pk)=φ(p)φ(k)=(p−1)k。
2、p∤kp\nmid kp∤k
此时p∣gcd(k,p)p|gcd(k,p)p∣gcd(k,p),φ(n)≠φ(pk)=φ(p)φ(k)\varphi(n)\neq\varphi(pk)=\varphi(p)\varphi(k)φ(n)=φ(pk)=φ(p)φ(k)。
为了推得正确的公式,我们先证明几个引理:
引理1:设ppp为质数,则φ(pk)=pk−pk−1\varphi(p^{k})=p^k-p^{k-1}φ(pk)=pk−pk−1
证明:因为pkp^{k}pk只含ppp一个质因子,故[1,pk][1,p^k][1,pk]内所有与ppp不互质的数的集合可表示成{x∣xp,1≤x≤pk−1,x∈N}\{x|xp,1\leq x\leq p^{k-1},x\in N\}{x∣xp,1≤x≤pk−1,x∈N}。这个集合的元素个数为pk−1p^{k-1}pk−1个,那么[1,pk][1,p^k][1,pk]内与pkp^kpk互质的元素个数即为pk−pk−1p^k-p^{k-1}pk−pk−1,即φ(pk)=pk−pk−1\varphi(p^{k})=p^k-p^{k-1}φ(pk)=pk−pk−1
引理2:设ppp为质数,则φ(pk+1)=p×φ(pk)\varphi(p^{k+1})=p\times\varphi(p^k)φ(pk+1)=p×φ(pk)
证明:由引理1,得:
φ(pk+1)=pk+1−pk=p(pk−pk−1)=p×φ(pk)\varphi(p^{k+1})=p^{k+1}-p^{k}=p(p^k-p^{k-1})=p\times\varphi(p^k)φ(pk+1)=pk+1−pk=p(pk−pk−1)=p×φ(pk)
由以上两个引理及积性函数性质,可推得:
设n=p×kn=p\times kn=p×k,ppp为素数且p∣kp|kp∣k,则有:φ(n)=p×φ(k)\varphi(n)=p\times \varphi(k)φ(n)=p×φ(k)
证明:设nnn不含因子ppp的最大因子为mmm,则:
φ(n)=φ(p×k)=φ(pt×m)=φ(pt)φ(m)=pφ(pt−1)φ(m)=pφ(pt−1m)=pφ(k)\varphi(n)=\varphi(p\times k)=\varphi(p^{t}\times m)=\varphi(p^t)\varphi(m)=p\varphi(p^{t-1})\varphi(m)=p\varphi(p^{t-1}m)=p\varphi(k)φ(n)=φ(p×k)=φ(pt×m)=φ(pt)φ(m)=pφ(pt−1)φ(m)=pφ(pt−1m)=pφ(k)
其中t≥2,t∈Nt\geq2,t\in Nt≥2,t∈N
所以,对于∀n∈N+∀p(p∣n)\forall n\in N^{+}\forall p(p|n)∀n∈N+∀p(p∣n),有:
(1) φ(n)=φ(p)φ(np)=(p−1)φ(np),p2∤n\varphi(n)=\varphi(p)\varphi(\frac{n}{p})=(p-1)\varphi(\frac{n}{p}),p^2\nmid nφ(n)=φ(p)φ(pn)=(p−1)φ(pn),p2∤n
(2) φ(n)=pφ(np),p2∣n\varphi(n)=p\varphi(\frac{n}{p}),p^2|nφ(n)=pφ(pn),p2∣n
所以,在线性筛的第二层循环时,每利用一个primeprimeprime筛去某个数时,直接利用上述公式将被筛数的φ\varphiφ值求出即可。
以上便是求φ(1)∼φ(n)\varphi(1)\sim\varphi(n)φ(1)∼φ(n)的O(n)O(n)O(n)方法
Code
#include<cstdio>
#include<iostream>
#define ri register int
using namespace std;
const int MAXN=4e4+20;
int N,prime[MAXN>>2],phi[MAXN],cnt,ans=3;
bool isprime[MAXN];
void Phi()//O(n)求1~N的欧拉函数
{
isprime[1]=true; phi[1]=1;
for(ri i=2;i<=N;++i)
{
if(!isprime[i])
{
prime[++cnt]=i;
phi[i]=i-1;
}
for(ri j=1;j<=cnt&&i*prime[j]<=N;++j)
{
isprime[i*prime[j]]=true;
if(i%prime[j]==0) phi[i*prime[j]]=phi[i]*prime[j];
else phi[i*prime[j]]=phi[i]*phi[prime[j]];
if(i%prime[j]==0) break;//这句话不能提前,否则无法处理phi[i*i](i均为质数)
}
}
}
int main()
{
scanf("%d",&N);
Phi();
if(N==1) { cout<<"0"; return 0; }
for(ri i=2;i<=N-1;++i)
ans+=phi[i]<<1;
cout<<ans;
return 0;
}
本文详细介绍了欧拉函数在解决数论问题中的应用,特别是如何利用欧拉函数解决洛谷P2158题。通过转化条件,作者指出能被看见的学生位置与x,y互质等价,从而引出欧拉函数φ(n)的定义。接着,文章提供了两种求解φ(1)到φ(n)的方法,包括平方根下界复杂度的求法和线性筛法,并通过引理证明解释了线性筛法中如何更新欧拉函数值。最后,给出了C++代码实现。
405

被折叠的 条评论
为什么被折叠?



