欧拉函数&乘法逆元

 

一、欧拉函数简单应用

·定义:

对于一个正整数n,它的欧拉函数的值即{p|p∈[1,n),p∈N+,p与n互质}的集合的大小,我们用φ(n)表示正整数n的欧拉函数

φ(n)=n(1-1/p1)(1-1/p2)……(1-1/pk),其中p1~pk为n的质因数

附证明:https://blog.csdn.net/paxhujing/article/details/51353672

·性质:

1)如果n是素数,那么φ(n)=n-1,逆向也成立

2)如果n是素数,k是正整数,那么φ(n^k)=(n-1)*n^(k-1)

证明:显然一共有n^k-1个正整数,其中能被n^k整除的有n*t,t∈{1,2……n^(k-1)-1},所以有[(n^k)-1]-[n^(k-1)-1]个

3)如果m,n是互质的正整数,那么φ(mn)=φ(m)φ(n)

证明:m,n没有公共约数,我们令p1~pk1表示m的质因数,q1~qk2表示n的质因数,我们由计算公式可得:

φ(m)φ(n)=m(1-1/p1)(1-1/p2)……(1-1/pk1)n(1-1/q1)(1-1/q2)……(1-1/qk2)

φ(mn)=mn(1-1/p1)(1-1/p2)……(1-1/pk1)(1-1/q1)(1-1/q2)……(1-1/qk2)

4)n=p1^a1*p2^a2*……*pk^ak为n的素数幂分解(根据唯一分解定理),那么φ(n)=n(1-1/p1)(1-1/p2)……(1-1/pk)

证明:你们一定行!

由性质3:

φ(n)=φ(p1^a1)φ(p2^a2)……φ(pk^ak)

=(p1-1)*p1^(a1-1)……(pk-1)*pk^(ak-1)

=p1^a1*……*pk^ak*(1-1/p1)*……*(1-1/pk)

5)一个数n的质因数的和=φ(n)*n/2

 

·练习:

#oj3623 Relatives

题目大意:求φ(n)

模板题,不难想到利用性质4来求φ(n),显然我们需要进行质因数分解,代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n;
int euler1(int m){//直接求 
	int ans=m;
	for(int i=2;i<=m;i++){
		if(m%i==0){
//			ans=ans*(1-1/i)=>
//			ans=ans-ans/i=>
			ans=ans/i*(i-1);//防止溢出 
			while(m%i==0)m/=i;
		}
	}return ans;
}
int euler2(int m){//O(√n)
	int ans=m;
	for(int i=2;i*i<=m;i++){//任意一个合数都有不大于根号n的约数 
		if(m%i==0){
			ans=ans/i*(i-1);
			while(m%i==0)m/=i;
		}
	}if(m>1)ans=ans/m*(m-1);//最后的pk 
	return ans;
}
#define MAXN 100001
int euler[MAXN];
int euler3(int m){//筛法求euler函数O(n),假的,千万级就跑得很慢了 
	for(int i=1;i<=m;i++)euler[i]=i;
	for(int i=2;i<=m;i++)if(euler[i]==i){//利用性质1 
		for(int j=i;j<=m;j+=i)euler[j]=euler[j]/i*(i-1);
	}return euler[m];
}
main(){
	while(~scanf("%lld",&n)&&n)cout<<euler1(n)<<""<<euler2(n)<<""<<euler3(n)<<"\n";

 

#oj3624 原根

 

题目大意:给定奇素数,求它的原根

原根是个数学符号,它的定理:n的原根为φ(φ(n)),当结论背下来吧,感兴趣的同学可以去网上找这方面的资料

 

#oj2904 MMT数

题目大意:给定一个数n,需要我们求n与x不互质且x不为n的约数的个数(x<=n)

发现正面求解不太好搞,我们考虑逆向求解

对于第一个条件(求互质):ans1=n-φ(n)

对于第二个条件(求约数个数):我们由素数幂分解得到ans2=(a1+1)(a2+1)……(ak+1)个(详见性质4)

于是我们就得到了最终答案:ans=n-ans1-ans2个?

注意1又是n的约数且含在了φ(n)中,所以算了两次,因此我们要+1</

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值