P2158 [SDOI2008]仪仗队&&欧拉函数的求法

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) (n1,n1),那么:设一名站在坐标 ( x , y ) (x,y) (x,y)处的学生:

​ 若该学生不能被看见,当且仅当 ∃ d ∈ N ( d ∣ x ∧ d ∣ y ) \exist d\in N(d|x\land d|y) dN(dxdy)

进一步转化条件:如果该学生能被看见,则说明 ┐ ∃ d ∈ N ( d ∣ x ∧ d ∣ y ) \urcorner\exist d\in N(d|x\land d|y) dN(dxdy),那么***从质因子分解的角度考虑***,此时 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+2i=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)=nppnpp1,故我们可以对 1 ∼ n 1\sim n 1n内的每个数进行质因子分解即可。

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)=n1即可。关键在于怎么把非素数的欧拉函数表示出来。

由于线性筛具有“每一个数只会被其最小的质因子筛去”的优秀性质,故我们可以考虑合数 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 pk

此时说明 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)=(p1)k

2、 p ∤ k p\nmid k pk

此时 p ∣ g c d ( k , p ) p|gcd(k,p) pgcd(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)=pkpk1

证明:因为 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\} {xxp,1xpk1,xN}。这个集合的元素个数为 p k − 1 p^{k-1} pk1个,那么 [ 1 , p k ] [1,p^k] [1,pk]内与 p k p^k pk互质的元素个数即为 p k − p k − 1 p^k-p^{k-1} pkpk1,即 φ ( p k ) = p k − p k − 1 \varphi(p^{k})=p^k-p^{k-1} φ(pk)=pkpk1

引理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+1pk=p(pkpk1)=p×φ(pk)

由以上两个引理及积性函数性质,可推得:

n = p × k n=p\times k n=p×k p p p为素数且 p ∣ k p|k pk,则有: φ ( 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φ(pt1)φ(m)=pφ(pt1m)=pφ(k)

其中 t ≥ 2 , t ∈ N t\geq2,t\in N t2,tN

所以,对于 ∀ n ∈ N + ∀ p ( p ∣ n ) \forall n\in N^{+}\forall p(p|n) nN+p(pn),有:

(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)=(p1)φ(pn),p2n

(2) φ ( n ) = p φ ( n p ) , p 2 ∣ n \varphi(n)=p\varphi(\frac{n}{p}),p^2|n φ(n)=pφ(pn),p2n

所以,在线性筛的第二层循环时,每利用一个 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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值