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 , y x,y x,y不存在相同的质因子,进而说明 x , y x,y x,y互质。
所以,站在坐标 ( x , y ) (x,y) (x,y)处的学生能被看见等价于 g c d ( x , y ) = 1 gcd(x,y)=1 gcd(x,y)=1( x , y x,y x,y互质)
考虑欧拉函数的定义: φ ( n ) = ∑ i = 1 n [ g c d ( 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]内与 n n n互质的数的个数。
那么,对于此题,答案即为 3 + 2 ∑ i = 2 n φ ( 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)的学生一定不能被看见)。
总结:涉及到 g c d ( x , y ) gcd(x,y) gcd(x,y)取值可能为1的问题,往往需要用到欧拉函数。
求 φ ( 1 ) ∼ φ ( n ) \varphi(1)\sim\varphi(n) φ(1)∼φ(n)的方法
O ( n n ) O(n\sqrt n) O(nn)求法
由于 φ ( n ) = n ∏ p p ∣ n p − 1 p \varphi(n)=n\prod_{p}^{p|n}\frac{p-1}{p} φ(n)=np∏p∣npp−1,故我们可以对 1 ∼ n 1\sim n 1∼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)做法利用了线性筛(欧拉筛)法的良好性质。
进行筛法的过程中,对于素数 n n n,直接令 φ ( n ) = n − 1 \varphi(n)=n-1 φ(n)=n−1即可。关键在于怎么把非素数的欧拉函数表示出来。
由于线性筛具有“每一个数只会被其最小的质因子筛去”的优秀性质,故我们可以考虑合数 n = p × k n=p\times k n=p×k在被它的最小质因子 p p p筛去时,利用 φ ( p ) \varphi(p) φ(p)与 φ ( k ) \varphi(k) φ(k)的值来求 φ ( n ) \varphi(n) φ(n)(此处线性筛外层循环枚举待筛数的最大因子的筛取性质证得:若 k k k为合数,当线性筛外层循环循环至 k k k时, k k k是否为素数及 φ ( k ) \varphi(k) φ(k)已被求出)。
1、 p ∣ k p|k p∣k
此时说明 n n n只含一个值为 p p p的素因子(不是只含一个素因子),由于欧拉函数满足积性函数的性质,故当 g c d ( k , p ) = 1 gcd(k,p)=1 gcd(k,p)=1时, φ ( n ) = φ ( p k ) = φ ( 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 ∤ k p\nmid k p∤k
此时 p ∣ g c d ( k , p ) p|gcd(k,p) p∣gcd(k,p), φ ( n ) ≠ φ ( p k ) = φ ( p ) φ ( k ) \varphi(n)\neq\varphi(pk)=\varphi(p)\varphi(k) φ(n)=φ(pk)=φ(p)φ(k)。
为了推得正确的公式,我们先证明几个引理:
引理1:设 p p p为质数,则 φ ( p k ) = p k − p k − 1 \varphi(p^{k})=p^k-p^{k-1} φ(pk)=pk−pk−1
证明:因为 p k p^{k} pk只含 p p p一个质因子,故 [ 1 , p k ] [1,p^k] [1,pk]内所有与 p p p不互质的数的集合可表示成 { x ∣ x p , 1 ≤ x ≤ p k − 1 , x ∈ N } \{x|xp,1\leq x\leq p^{k-1},x\in N\} {x∣xp,1≤x≤pk−1,x∈N}。这个集合的元素个数为 p k − 1 p^{k-1} pk−1个,那么 [ 1 , p k ] [1,p^k] [1,pk]内与 p k p^k pk互质的元素个数即为 p k − p k − 1 p^k-p^{k-1} pk−pk−1,即 φ ( p k ) = p k − p k − 1 \varphi(p^{k})=p^k-p^{k-1} φ(pk)=pk−pk−1
引理2:设 p p p为质数,则 φ ( p k + 1 ) = p × φ ( p k ) \varphi(p^{k+1})=p\times\varphi(p^k) φ(pk+1)=p×φ(pk)
证明:由引理1,得:
φ ( p k + 1 ) = p k + 1 − p k = p ( p k − p k − 1 ) = p × φ ( p k ) \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 × k n=p\times k n=p×k, p p p为素数且 p ∣ k p|k p∣k,则有: φ ( n ) = p × φ ( k ) \varphi(n)=p\times \varphi(k) φ(n)=p×φ(k)
证明:设 n n n不含因子 p p p的最大因子为 m m m,则:
φ ( n ) = φ ( p × k ) = φ ( p t × m ) = φ ( p t ) φ ( m ) = p φ ( p t − 1 ) φ ( m ) = p φ ( p t − 1 m ) = 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 ∈ N t\geq2,t\in N t≥2,t∈N
所以,对于 ∀ n ∈ N + ∀ p ( p ∣ n ) \forall n\in N^{+}\forall p(p|n) ∀n∈N+∀p(p∣n),有:
(1) φ ( n ) = φ ( p ) φ ( n p ) = ( p − 1 ) φ ( n p ) , p 2 ∤ 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 φ ( n p ) , p 2 ∣ n \varphi(n)=p\varphi(\frac{n}{p}),p^2|n φ(n)=pφ(pn),p2∣n
所以,在线性筛的第二层循环时,每利用一个 p r i m e prime prime筛去某个数时,直接利用上述公式将被筛数的 φ \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;
}