【强基】欧拉函数与积性函数

Part 1:前置知识

线性筛
#include<bits/stdc++.h>
using namespace std;

const int N=100001;

int n,v[N],prime[N],tot;

void primes(int n)
{
   
	for(int i=2; i<=n; i++)
	{
   
		if(!v[i])
		{
   
			v[i]=i;
			prime[++tot]=i;
		}
		
		for(int j=1; j<=tot; j++)
		{
   
			if(prime[j]>v[i] || prime[j]>n/i)
				break;
			v[i*prime[j]]=prime[j];
		}
	}
}

int main()
{
   
	cin>>n;
	
	primes(n);
	
	for(int i=1; i<=tot; i++)
		cout<<prime[i]<<" ";
		
	return 0;
}

Part 2:欧拉函数

  • 定义:欧拉函数 φ ( n ) φ(n) φ(n) 表示小于等于 n n n,且与 n n n 互质的正整数的个数。
  • 公式
    若在算数基本定理中, n = p 1 c 1 p 2 c 2 . . . p m c m n=p_1^{c_1}p_2^{c_2}...p_m^{c_m} n=p1c1p2c2...pmcm p p p 为质数),则由容斥原理: φ ( n ) = n ∗ p 1 − 1 p 1 ∗ p 2 − 2 p 2 ∗ . . . ∗ p m − m p m = n ∗ ∏ p ∣ n ( 1 − 1 p ) φ(n)=n*\dfrac{p_1-1}{p_1}*\dfrac{p_2-2}{p_2}*...*\dfrac{p_m-m}{p_m}=n*\prod\limits_{p\mid{n}}{(1-\dfrac{1}{p})} φ(n)=np1p11p2p22...pmpmm=npn(1p1)
    关于此公式的证明,读者可自行推导

Part 3:积性函数

  • 定义:若一个定义在正整数域上的函数 f f f,当 x , y x,y x,y 互质时,有 f ( x y ) = f ( x ) ∗ f ( y ) f(xy)=f(x)*f(y) f(xy)=f(x)f(y),则称函数 f f f 是积性函数
  • 欧拉函数是积性函数,即:若 a , b a,b a,b 互质,则 φ ( a b ) = φ ( a ) ∗ φ ( b ) φ(ab)=φ(a)*φ(b) φ(ab)=φ(a)φ(b)

    证明:由欧拉函数计算公式可得

  • d ( n ) d(n) d(n) 表示 n n n 的约数个数,则 d ( n ) d(n) d(n) 是积性函数
  • s ( n ) s(n) s(n) 表示 n n n 所有约数的和,则 s ( n ) s(n) s(n) 是积性函数
  • 所有的积性函数可以用线性筛求解!!!

Part 4:欧拉函数常见的性质

  1. n n n 是质数,则 φ ( n ) = n − 1 φ(n)=n-1 φ(n)=n1
  2. n = p k n=p^k n=pk,且 p p p 为质数,则 φ ( n ) = ( p − 1 ) ∗ p k − 1 φ(n)=(p-1)*p^{k-1} φ(n)=(p1)pk1
  3. p p p 是质数,且 { p ∣ n ⇒ φ ( n q ) = φ ( n ) ∗ q p ∤ n ⇒ φ ( n q ) = φ ( n ) ∗ ( q − 1 ) \begin{cases}p\mid{n}&\Rightarrowφ(nq)=φ(n)*q\\p\nmid{n}&\Rightarrowφ(nq)=φ(n)*(q-1)\end{cases} { pnpnφ(nq)=φ(n)qφ(nq)=φ(n)(q1)
  4. n = ∑ d ∣ n φ ( d ) n=\sum\limits_{d\mid{n}}{φ(d)} n=dnφ(d)
  5. φ ( a b ) = φ ( a ) ∗ φ ( b ) ∗ d φ ( d ) φ(ab)=φ(a)*φ(b)*\frac{d}{φ(d)} φ(ab)=φ(a)φ(b)φ(d)d,其中 d = gcd ⁡ ( a , b ) d=\gcd(a,b) d=gcd(a,b)

Part 5:例题

【模板题】求 φ(n)

解题思路
  • 我们已知 φ ( n ) φ(n) φ(n) 的计算公式,所以只需对 n n n 进行质因数分解即可
代码
#include<bits/stdc++.h>
using namespace std;

const int N=100001;

int n;

int GetPhi(int n)
{
   
	int ans=n;
	for(int i=2; i*i<=n; i++) //分解质因数
	{
   
		if(n%i==0)
		{
   
			ans=ans*(i-1)/i; //计算公式
			while(n%i==0)
				n/=i;
		}
	} 
	
	if(n>1) //还剩下一个较大的质数
		ans=ans*(n-1)/n;
	
	return ans;	
}

int main()
{
   
	cin>>n;
	cout<<GetPhi(n);
		
	return 0;
}

【模板题】求 φ(1) ~ φ(n)

解题思路
  • 由于欧拉函数是积性函数,所以我们考虑用线性筛求解
  • 从欧拉函数性质 3 3 3 出发,在线性筛中,每个合数 x x x 都会被它最小的质因子 p p p 筛去,此时我们就可以用 p p p ( ( ( p − 1 ) p-1) p1) φ ( x / p ) φ(x/p) φ(x/p) 来推出 φ ( x ) φ(x) φ(x) ,具体是 p p p 还是 p − 1 p-1 p1,要看 x / p x/p x/p,即我们外层循环的 i i i 是否是 q q q 的倍数;而对于每个质数 y y y,由性质 1 1 1<
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值