欧拉定理
欧拉定理:
前言:
数论以外怎么还有这么多欧拉定理??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
题外话:
扩展欧拉定理证明是怎么想出来的啊,就真反常规

浙公网安备 33010602011771号