欧拉定理

欧拉定理:


前言:

数论以外怎么还有这么多欧拉定理??stO @Euler Orz


前置需要:

欧拉函数\(\varphi(x)\) 表示小于 \(x\) 的正整数中和 \(x\) 互质的数的个数。


欧拉定理:

\(a,m\) 互质时,\(a^{\varphi(m)}\equiv1\pmod m\)

证明:

\(x_{1,2,\cdots,\varphi(m)}\) 为小于 \(m\) 且与 \(m\) 互质的正整数,\(p_i=a\times x_i\)

引理1:

\(\forall i\neq j,p_i\not\equiv p_j\pmod m\)

因为所有 \(x\) 小于 \(m\),所以 \(\left|x_i-x_j\right|<m\)

\(x_i\neq x_j\)

所以 \(m\nmid x_i-x_j\)

\(a,m\) 互质,

所以 \(m\nmid a(x_i-x_j)\)

\(p_i\not\equiv p_j\pmod m\)

意为所有 \(p_i\%m\) 互不相等。

引理2:

\(\gcd(p_i\%m,m)=1\)

由于 \(a,m\) 互质,\(x_i,m\) 互质,所以 \(p_i,m\) 互质。

\(p_i=km+r\)\(r\)\(p_i\%m\)

\(d=\gcd(r,m)\),显然 \(m,r\) 都是 \(d\) 倍数。

\(p_i=d(k*\dfrac{m}{d}+\dfrac{r}{d})\)

所以\(\gcd(p_i,m)=d\),又 \(p_i,m\) 互质,所以 \(d=\gcd(r,m)=1\)

意为 \(p_i\%m\)\(m\) 互质,即 \(p_i\%m\)\(\varphi(m)\) 种取值。

证明:

结合引理1和引理2,所有 \(p_i\%m\) 互不相等且 \(p_i\%m\)\(\varphi(m)\) 种取值。

所以 \(p_{1,2,\cdots,\varphi(m)}\%m\)\(x_{1,2,\cdots,\varphi(m)}\) 是一一对应的。

所以 \(\prod\limits_{i=1}^{\varphi(m)}p_i\equiv \prod\limits_{i=1}^{\varphi(m)}x_i\pmod m\)

所以 \(\prod\limits_{i=1}^{\varphi(m)}(x_i\times a)\equiv \prod\limits_{i=1}^{\varphi(m)}x_i\pmod m\)

所以 \(a^{\varphi(m)}*\prod\limits_{i=1}^{\varphi(m)}x_i\equiv \prod\limits_{i=1}^{\varphi(m)}x_i\pmod m\)

所以 \(a^{\varphi(m)}\equiv 1\pmod m\)

证毕。

实际运用时常写成:

\(a,m\) 互质时,\(a^b\equiv a^{(b\mod \varphi(m))}\pmod m\)


扩展欧拉定理:

显然欧拉定理有个硬伤是 \(a,m\) 互质,扩展欧拉定理则没有这个限制,可以处理更多情况。

\(b\geq\varphi(m)\) 时,\(a^b\equiv a^{(b \mod\varphi(m)+\varphi(m))}\pmod m\)

证明:

\(m\) 的一个质因子 \(p\),令 \(m=p^r\times s\),有 \(\gcd(p,s)=1\)

因为欧拉函数是积性函数,所以有

  • \(\varphi(m)=\varphi(p^r)*\varphi(s)\)

由欧拉定理可知 \(p^{\varphi(s)}\equiv1\pmod s\),所以有 \((p^{\varphi(s)})^{\varphi(p^r)}\equiv1^{\varphi(p^r)}\pmod s\)

  • \(p^{\varphi(m)}\equiv1\pmod s\)

所以可设 \(p^{\varphi(m)}=ks+1\),两边同乘 \(p^{r}\)\(p^{\varphi(m)+r}=km+p^r\)

  • \(p^{\varphi(m)+r}\equiv p^r\pmod m\)

\(b\geq r\) 时,

  • \(p^b\equiv p^{b-r}*p^r\equiv p^{b-r}*p^{\varphi(m)+r}\equiv p^{b+\varphi(m)}\pmod m\)

\(b=b-\varphi(m)\) 则有

  • \(b-\varphi(m)\geq r\) 时,\(p^{b-\varphi(m)}\equiv p^b\pmod m\)

因为 \(\varphi(m)=\varphi(p^r)*\varphi(s)\),所以 \(\varphi(p^r)\leq\varphi(m)\)

又有 \(r\leq\varphi(p^r)\) ,感性理解一下,当 \(r=1\)\(p\) 最小为 \(2\),$\varphi(p) $ 为 \(1\),当 \(r\) 增加 \(1\) 时,\(\varphi(p)\)\(p\),显然有 \(r\leq\varphi(p^r)\)

  • 所以有 \(r\leq \varphi(m)\)

所以有

  • \(b\geq 2*\varphi(m)\) 时,\(p^{b-\varphi(m)}\equiv p^b\pmod m\)

整理后可得

  • \(b\geq\varphi(m)\) 时,\(p^b\equiv p^{(b \mod\varphi(m)+\varphi(m))}\pmod m\)

\(a\) 质因数分解,对于是 \(m\) 质因子的 \(p\) 有上式,对于不是 \(m\) 质因子的 \(p\) 有欧拉定理\(p^b\equiv p^{(b\mod \varphi(m))}\equiv p^{(b \mod\varphi(m)+\varphi(m))}\pmod m\) ,同样满足上式,所以可以全部乘起来合并,就得到了扩展欧拉定理:

\(b\geq\varphi(m)\) 时,\(a^b\equiv a^{(b \mod\varphi(m)+\varphi(m))}\pmod m\)


例题:

欧拉定理一般用于模意义下高次幂降次工具人++,所以一般会组合其他东西来考比如毒瘤数据结构

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

题目描述已经非常清楚,但由于次数 \(b\) 达到了高精的范围,所以我们要用欧拉定理降次,又不保证模数 \(m\) 与底数 \(a\) 互质,所以用扩展欧拉定理。

扩展欧拉定理具体写出来是这样的:

\(a^b\equiv \begin{cases}a^b\ (\ b\leq \varphi(m)\ )\\a^{(b \mod\varphi(m)+\varphi(m))}\ (\ b> \varphi(m)\ )\end{cases}\pmod m\)

\(b> \varphi(m)\) 时我们可以边输入 \(b\) 边模 $ \varphi(m)$,最后再加上 $ \varphi(m)$。但注意到因为 \(a,m\) 没有互质的条件,当 \(b\leq \varphi(m)\)\(a^b\equiv a^{b+\varphi(m)}\pmod m\) 不一定成立。所以需要在输入时判断 \(b\)\(\varphi(m)\) 的大小关系,从而决定是否加上 $ \varphi(m)$。

代码:
#include<bits/stdc++.h>
using namespace std;
#define int long long
int a,b,m;
int phim;
int flag;
int getphi(int n){
	if(n==1)return 1;
	int ans=n;
	for(int i=2;i*i<=n;i++){
		if(n%i==0)ans-=ans/i;
		while(n%i==0)n/=i;
	}
	if(n>1)ans-=ans/n;
	return ans;
}
int qpow(int a,int b,int mod){
	int ans=1;
	while(b){
		if(b&1)ans=(ans*a)%mod;
		a=(a*a)%mod;
		b>>=1;
	}
	return ans;
}
int getb(){
	int ans=0;
	char c=getchar();
	while(c>'9'||c<'0')c=getchar();
	while(c>='0'&&c<='9'){
		ans=ans*10+c-'0';
		if(ans>phim){
			flag=true;
			ans%=phim;
		}
		c=getchar();
	}
	return ans;
}
signed main(){
	cin>>a>>m;
	phim=getphi(m);
	b=getb();
	if(flag)b+=phim;
	cout<<qpow(a,b,m);
	return 0;
}

2.P4139 上帝与集合的正确用法

题意也被简单地概括了,即:

\(2^{2^{2^\cdots}}\operatorname{mod}\ p\)

显然左边是一个无穷大,无穷大也能降次吗?欧拉定理又没有规定数的范围,当然是可以的。但注意到不保证 \(2,p\) 互质,所以考虑扩展欧拉定理。把它写出来:

\(a^b\equiv \begin{cases}a^b\ (\ b\leq \varphi(p)\ )\\a^{(b \mod\varphi(p)+\varphi(p))}\ (\ b> \varphi(p)\ )\end{cases}\pmod p\)

发现此时的 \(b\) 等于左边的 \(a^b\) 也是 \(2^{2^{2^\cdots}}\),显然大于 \(\varphi(p)\),所以发现

\(2^{2^{2^\cdots}}\equiv 2^{(2^{2^{2^\cdots}}\mod\varphi(p)+\varphi(p))}\pmod p\)

观察这一坨:\(2^{2^{2^\cdots}} \mod\varphi(p)+\varphi(p)\)

右边的\(\varphi(p)\) 显然可以预处理出来,而左边的\(2^{2^{2^\cdots}} \mod\varphi(p)\) 相比 \(2^{2^{2^\cdots}} \mod p\) 规模在减小,所以可以不断从 \(p\) 递归到 \(\varphi(p)\)。递归到最后会递归到 \(p=1\) 此时就可以返回 \(2^{2^{2^\cdots}} \mod 1=0\)。这样上面这坨就能算出来,再用快速幂算一下 \(2^{(2^{2^{2^\cdots}}\mod\varphi(p)+\varphi(p))}\) 就可以回溯回去了。

递归思想建立了我们可以稍加优化,由于 \(\varphi(m)\) 不断减小,所以我们可以用欧拉筛预处理出 \(1\)\(p_{max}\) 的所有 \(\varphi\) 值。且不同的 \(p\) 计算时可能会有重复,所以我们还可以记忆化搜索。另外在快速幂算的时候次数最大有 \(2p\) 次,会爆 int,所以还要用long long

时间复杂度分析:由于偶数取 \(\varphi\) 至少减半,奇数会变成偶数,所以复杂度是 \(\log\) 的。总的大概是 \(O(p_{max}+T\log p)\)

代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int prime[700005];
int phi[10000005];
void getphi(int n){
	phi[1]=1;
	for(int i=2;i<=n;i++){
		if(phi[i]==0){prime[++prime[0]]=i;phi[i]=i-1;}
		for(int j=1;j<=prime[0]&&prime[j]*i<=n;j++){
			if(i%prime[j]==0){phi[i*prime[j]]=phi[i]*prime[j];break;}
			phi[i*prime[j]]=phi[i]*(prime[j]-1);
		}
	}
}
ll qpow(ll a,ll b,ll p){
	ll ans=1;
	while(b){
		if(b&1)ans=(ans*a)%p;
		a=(a*a)%p;
		b>>=1;
	}
	return ans;
}
int T,maxp;
int p[1005];
ll ans[10000005];
ll getans(ll p){
	if(ans[p]!=-1)return ans[p];//记忆化搜索 
	ll b=getans(phi[p])+phi[p];
	ans[p]=qpow(2,b,p);
	return ans[p];
}
signed main(){
	scanf("%d",&T);
	for(int i=1;i<=T;i++){
		scanf("%d",&p[i]);
		maxp=max(maxp,p[i]);
	}
	
	getphi(maxp);//预处理phi值 
	memset(ans,-1,sizeof(ans));
	ans[1]=0;//ans[i]代表2^2^... mod i的值 
	
	for(int i=1;i<=T;i++)
		printf("%lld\n",getans(p[i]));
	return 0;
}

3.例题推荐:

这里附上两道数据结构+欧拉定理的毒瘤题,有兴趣可以做。反正我没兴趣。

P3747 [六省联考 2017] 相逢是问候.
P3934 [Ynoi2016] 炸脖龙 I

题外话:

扩展欧拉定理证明是怎么想出来的啊,就真反常规

posted @ 2021-06-01 21:30  llmmkk  阅读(347)  评论(0)    收藏  举报