【学习笔记】欧拉函数 欧拉定理 扩展欧拉定理

欧拉函数 欧拉定理 学习笔记

之前没怎么搞过数论,现在来学学 从最简单的搞起QwQ

欧拉函数

先说几个简单的概念

互质大家应该都懂,就不说了(除了1以外没有其他公因子)

剩余类、完全剩余系、缩系就不说了,不是什么高级的东西,感兴趣可以问我

在数论,对正整数n,欧拉函数φ(n)是小于n的正整数中与n互质的数的数目

欧拉函数的推导

公式最后再说,先推一下,需要大力分讨

(1)n=1,则φ(1)=1,1与任何数都互质

(2)n是质数,φ(n)=n1

(3)n是质数的某次方,n=pk(p为质数,k1φ(n)=pkpk1

因为从1n一共有pk个数,其中不与n互质的一定为p的倍数共有pk1

柿子亦可化简为φ(pk)=pk(11p)k=1时得到上述第二种情况

(4)n可分解为两互质整数之积,n=p1p2φ(n)=φ(p1p2)=φ(p1)φ(p2)

证明需用CRT,有点麻烦,记住就行了(其实就是积性函数)

(5)任意正整数都可以写成质数之积,n=p1k1p2k2pmkm

根据(4)可得φ(n)=φ(p1k1)φ(p2k2)φ(pmkm)

再根据(3)可得φ(n)=p1k1(11p1)p2k2(11p2)pmkm(11pm)

φ(n)=p1k1p2k2pmkm(11p1)(11p2)(11pm)

最终得φ(n)=n(11p1)(11p2)(11pm)

综上所述:φ(n)=ni=1m(1pi)

这样我们就得到了欧拉函数的通项公式,考虑如何求解

欧拉函数就用欧拉筛(bushi

线性筛素数

保证每个数被最小质因子筛去,通过break做到O(n)

void oula()
{
	memset(vis,false,sizeof(vis));
	for(int i=2;i<=n;i++)
	{
		if(!vis[i]) prime[++cnt]=i;
		for(int j=1;j<=cnt && i<=n/prime[j];j++)
		{
			vis[i*prime[j]]=true;
			if(i%prime[j]==0) break;
		}
	}
}

线性筛欧拉函数

用到的三个性质 设d=nppn的最小质因子)

  1. n为质数,φ(n)=n1
  2. pd的一个质因子,φ(n)=φ(d)×p
  3. pd互质,φ(n)=φ(d)×φ(p)
void oula()
{
	memset(vis,false,sizeof(vis));
	phi[1]=1,cnt=0;
	for(int i=2;i<=n;i++)
	{
		if(!vis[i]) prime[++cnt]=i,phi[i]=i-1; //性质1 
		for(int j=1;j<=cnt && i<=n/prime[j];j++)
		{
			vis[i*prime[j]]=true; 
			if(i%prime[j]==0)
			{
				phi[i*prime[j]]=phi[i]*prime[j]; //性质2 
				break;
			}
			phi[i*prime[j]]=phi[i]*(prime[j]-1); //性质3 
		}
	}
}

求某个数的欧拉函数值

int oula(int x)
{
	int res=x;
	for(int i=2;i*i<=x;i++)
	{
		if(x%i==0) res=res/i*(i-1);
		while(x%i==0) x/=i;
	}
	if(x>1)return res=res/x*(x-1);
	else return res;
}

欧拉函数性质

  1. 欧拉函数是积性函数(特别的φ(2n)=φ(n)

  2. n=d|nφ(d) n的所有因子的欧拉函数值之和为n

  3. 还有一部分就是上面证明中提到的了qwq

欧拉定理

gcd(a,m)=1,则aφ(m)1(mod m)

欧拉定理的证明

首先举出几个引理

引理一

  • abc三个任意整数与正整数m,满足mc互质,则如果a×cb×c(mod m),那么ab(mod m)
  • 证明:由同余的同加性可知,a×cb×c0(mod m),即(ab)×c0(mod m)gcd(c,m)=1,因此c不为m的倍数,即(ab)m的倍数,(ab)0(mod m)ab(mod m)

引理二

  • a,b属于m的缩系,则a×b mod m也属于m的缩系
  • 证明:若a,bm互质,则a×b也与m互质(因为a,b中都没有与m相同的因子,所以a×b也没有与m相同的因子),因此(可由反证法得知)a×b mod m也与m互质

引理三

  • n,m互质,且S1={a1,a2,…,am}为m的完全剩余系,则S2={na1 mod m,na2 mod m,…,nam mod m}也构成m的完全剩余系
  • 证明:假设nainaj(mod m),由引理一可知aiaj(mod m),因为是其都属于m的完全剩余系,所以aiaj(mod m),产生了矛盾,因此nainaj(mod m),在S2中两两之间都满足这一性质,即满足其为m的完全剩余系

引理四

  • n,m互质,且S1={a1,a2,…,aφ(m)}为m的简化剩余系(缩系),则S2={na1 mod m,na2 mod m,…,naφ(m) mod m}也为其简化剩余系
  • 证明:首先由引理三推出一个完全剩余系,然后根据引理二可证明此引理

证明欧拉定理

m的简化剩余系为{a1,a2,…,aφ(n)}

aφ(m)a1a2aφ(m)=(aa1)(aa2)(aaφ(m))a1a2aφ(m)(mod m)

aφ(m)a1a2aφ(m)a1a2aφ(m)(mod m)

后者(a1a2aφ(m))均与m互质,直接由引理一得到aφ(m)1(mod m)

欧拉定理的一点小扩展

ababmodφ(n)(mod n)

证明

b=k×φ(n)+rr=bmodφ(n),则abak×φ(n)+rar×aφ(n)×kar×(aφ(n))k(mod n)

因为aφ(n)1(mod n),所以abar(mod n),即ababmodφ(n)(mod n)

扩展欧拉定理

由上得ababmodφ(n)(mod n)

a,mZ(不要求互质)时有

ab{abmodφ(m)b<φ(m)a(bmodφ(m))+φ(m)bφ(m) (mod m)

证明扩展欧拉定理

m的质因数p,满足m=pr×s,gcd(p,s)=1

欧拉定理得pφ(s)1(mod m)φ(m)=φ(s)φ(pr)

pφ(m)(pφ(s))φ(pr)1(φ(pr))1(mod s)

pφ(m)=ks+1,则pφ(m)+r=pφ(m)×pr=(ks+1)×prs=mpr,得到pφ(m)+r=(km+pr)

pφ(m)+rpr(mod m)

br时,pbpbr×prpbr×pφ(m)+rpb+φ(m)(mod m)

rφ(pr)φ(m)bφ(m)φ(pr)r

因此可得abapr,即aprab的一个因子,也是a(bmodφ(m))+φ(m)的因子

aba(bmodφ(m))+φ(m)0(mod pr)

然后质因子分解mpiri,按照上述方法,可得到每个piri都满足aba(bmodφ(m))+φ(m)0(mod piri)

综上所述:扩展欧拉定理成立

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#define int long long

using namespace std;

int phi,a,m,b,flag;

int ksm(int a,int b)
{
	int ans=1;
	for(;b;b>>=1,a=(a*a)%m)
	{
		if(b&1) ans=(ans*a)%m;
	}
	return ans;
}

int oula(int x)
{
	int res=x;
	for(int i=2;i*i<=x;i++)
	{
		if(x%i==0) res=res/i*(i-1);
		while(x%i==0) x/=i;
	}
	if(x>1)return res=res/x*(x-1);
	else return res;
}

signed main()
{
	scanf("%d%d",&a,&m);
	
	int mid=m;	phi=oula(m); char ch;
	while ((ch=getchar())<'0' || ch>'9');
	while (b=b*10ll+(ch^48),(ch=getchar())>='0' && ch<='9')
	{
		if (b>=phi) flag=1,b%=phi;	
	}
	if(b>=phi) b%=phi,flag=true;
	if(flag) b+=phi;
	
	printf("%lld",ksm(a,b));
	
	return 0;
}

例题

上帝与集合的正确用法

差不多是个裸题,柿子都给出来了,直接递归就好,然后用扩展欧拉定理求解即可

AC code

点击查看代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#define int long long

using namespace std;

const int maxn=1e7+5;

inline int read()
{
	int w=0,f=1;
	char ch=getchar();
	while(ch<'0' || ch>'9')
	{
		if(ch=='-') f=-1;
		ch=getchar();
	}
	while(ch>='0' && ch<='9')
	{
		w=(w<<3)+(w<<1)+(ch^48);
		ch=getchar();
	}
	return w*f;
}

int t,p,cnt;
int phi[maxn];
bool vis[maxn];
int prime[maxn];

int ksm(int a,int b,int mod)
{
	int ans=1;
	for(;b;b>>=1,a=(a*a)%mod)
	{
		if(b&1) ans=(ans*a)%mod;
	}
	return ans%mod;
}

void oula()
{
	phi[1]=1,cnt=0;int n=maxn-5;
	for(int i=2;i<=n;i++)
	{
		if(!vis[i]) phi[i]=i-1,prime[++cnt]=i;
		for(int j=1;i<=n/prime[j] && j<=cnt;j++)
		{
			vis[i*prime[j]]=true;
			if(i%prime[j]==0)
			{
				phi[i*prime[j]]=phi[i]*prime[j];break;
			}
			phi[i*prime[j]]=phi[i]*(prime[j]-1);
		}
	}
}

int solve(int x)
{
	if(x==1) return 0;
	return ksm(2,solve(phi[x])+phi[x],x);
}

void work()
{
	printf("%lld\n",solve(read()));
}

signed main()
{
	oula();t=read();while(t--) work();
	
	return 0;
}

总结

其实就三句有用的

  1. 欧拉公式 φ(x)=x×i=1k(11pi)
  2. 欧拉定理 gcd(a,m)=1aφ(m)1(mod m)
  3. 扩展欧拉定理 ab{abmodφ(m)b<φ(m)a(bmodφ(m))+φ(m)bφ(m) (mod m)
posted @   NinT_W  阅读(121)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
点击右上角即可分享
微信分享提示