专题 Euler 定理 & EXEuler 定理的概述

概念解释

本文主要介绍关于 Euler,以及 EXEuler 的编码方式还有它们的应用。数学理论会涉及到,但是不会很多。更多的内容会在专门的合集里。

算法分析

在介绍 Euler 定理之前,笔者首先需要介绍 Fermat 小定理。它的基本内容是:

定理1(Fermat-Euler 定理)

\((a,m)=1\),则有 \(a^{\varphi(m)} \equiv 1 (\mod m )\)\((1)\)

特别地,当 \(p\in Prime\) 时,对任意的 \(a\),有 \(a_{p} \equiv a (\mod p)\)\((2)\)

通常,\((2)\) 为 Fermat 小定理,而 \((1)\) 为 Euler 定理。对于这些内容的证明,我们放到初等数论的合集了。

这两个定理的作用一般是求逆。结合快速幂去求,这里就不放模板了,因为也没有,毕竟是一个工具类型的定理。

下面我们再介绍一下 EXEuler。这个本来在初等数论上笔者没有找到参考资料,所以在这里就详细说一下。

定理2(EXEuler,扩展欧拉定理)

对于任意的 \(a,k,n\),有 \(a^{k} \equiv a^{k \mod \varphi(n) + \varphi(n)} (\mod n)\)

事实上,这个定理的证明并不好证。这里也只是介绍它的用途,对于我们编码已然足够了。更多的理论推导,放在了合集里。

这个定理的作用是降幂。给出模板题,感受一下。

luogu.P5091 【模板】扩展欧拉定理

参考代码

#include<iostream>
#define int long long 
#define rei register int 
using namespace std;
int a,m;
string b;
int fpow(int x,int y)
{
	int ans=1;
	while(y)
	{
		if(y&1) ans=ans*x%m;
		x=x*x%m;
		y>>=1;
	}
	return ans;
}
int get_phi(int n)
{
	int ans=n;
	for(rei i=2;i<=n/i;i++)
		if(n%i==0)	
		{
			ans=ans/i*(i-1);
			while(n%i==0) n/=i;
		}
	if(n>1) ans=ans/n*(n-1);
	return ans;
}
int depow(int x)
{
	int temp=0,f=0;
	for(rei i=0;i<b.size();i++)
	{
		temp=temp*10+b[i]-'0';
		if(temp>=x) f=1,temp%=x;
	}
	if(f) temp+=x;
	return temp;
}
signed main()
{
	cin>>a>>m;
	cin>>b;
	int phi_m=get_phi(m);
	int y=depow(phi_m);
	cout<<fpow(a,y);
	return 0;
}

细节研讨

利用这个手段降幂,然后再用快速幂去求。这样是合理的手段。

总结归纳

配套的理论证明对应在《初等数论》的合集里有。

posted @ 2025-08-07 09:28  枯骨崖烟  阅读(6)  评论(0)    收藏  举报