欧拉定理及扩展欧拉定理

· · 算法·理论

整除

n\bmod p=0p|n,即 p 可以被 n 整除。

同余

a,b 除于 p 的余数相同,则记为 a\equiv b\pmod p

通常情况下 p\in \mathbb{N^\ast}

欧拉函数

$\varphi(n)$ 是积性函数,即满足 $\gcd(n,m)=1,\varphi(nm)=\varphi(n)\times\varphi(m)$。 单个欧拉函数求法: $$\varphi(n)=n\prod\limits_{p|n}(1-\frac{1}{p_i})$$ ``` int GetPhi(int n) { int ans = n; for(int i = 2;i * i <= n;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; } ``` 证明: 设 $a=p^k(k\in\mathbb{N^{\ast}})$ 且 $p$ 是质数,则显然 $a$ 与 $p,2p,\dots,p^{k-1}p$ 不互质,那么 $\varphi(a)=p^k-p^{k-1}=p^k(1-\frac{1}{p})$。 将 $n$ 唯一分解: $$n=\prod\limits_{p|n}p_i^{k_i}$$ 则由积性函数得: $$\varphi(n)=\prod\limits_{p|n}\varphi(p_i^{k_i})=\prod\limits_{p|n}p_i^{k_i}(1-\frac{1}{p_i})=n\prod\limits_{p|n}(1-\frac{1}{p_i})$$ 由于欧拉函数是积性函数,所以可以直接线性筛。 ``` void Sieve(int siz,int p[],int phi[]) { int ncnt = 0; vector<int> vis(siz + 5); phi[1] = 1; for(int i = 2;i <= siz;i++) { if(!vis[i]) { p[++ncnt] = i; phi[i] = i - 1; } for(int j = 1;j <= ncnt && i * p[j] <= siz;j++) { vis[i * p[j]] = 1; if(i % p[j] == 0) { phi[i * p[j]] = phi[i] * p[j]; //p[j]是i*p[j]的最小质因子 break; } phi[i * p[j]] = phi[i] * phi[p[j]]; } } } ``` ## 欧拉定理 若 $\gcd(a,p)=1,a^{\varphi(p)}\equiv 1\pmod p$。 证明: 这里不包含 $p=1$ 的情况。 由于 $\varphi(p)<p$,那么由上面的方法可得 $a,2a,\dots,\varphi(p)a$ 在模 $p$ 后互不相同。 $$\prod\limits_{i=1}^{\varphi(p)}A_i\equiv\prod\limits_{i=1}^{\varphi(p)}(A_ia)\pmod p$$ $$\varphi(p)!\equiv \varphi(p)!a^{\varphi(p)}\pmod p$$ $$a^{\varphi(p)}\equiv 1\pmod p$$ 特别的,当 $p$ 是质数时 $\varphi(p)=p-1$,这就等价于 $a^{p-1}\equiv 1\pmod p$ 也就是费马小定理。 ### 扩展欧拉定理 $$a^b=\begin{Bmatrix}a^{b\bmod\varphi(p)},\gcd(a,p)=1\\a^b,\gcd(a,p)\ne1,b<\varphi(p),\pmod p\\a^{b\bmod\varphi(p)+\varphi(p)},\gcd(a,p)\ne1,b\ge \varphi(p)\end{Bmatrix}$$ 简单来说就是若 $\gcd(a,p)\ne 1,b\ge\varphi(p)$ 则 $a^b\equiv a^{b\bmod\varphi(p)+\varphi(p)}\pmod p$,这可用于 $b$ 很大时降次。 证明: 第一行式子由欧拉定理易得,不证。 第二与第三行: 我们取 $m|p$ 且 $m$ 是质数,令 $k=\frac{p}{m}$。 由欧拉定理得:$a^{\varphi(m)}\equiv 1\pmod m$。 因为 $\varphi(m)|\varphi(p)$,所以 $a^{\varphi(p)}\equiv 1\pmod m$。 同时乘 $a^k$,得到 $a^{\varphi(p)+k}\equiv a^k\pmod p$。 所以 $a^b\equiv a^{b-k+k}\equiv a^{\varphi(p)+b}\pmod p$。 因为 $b\ge\varphi(p)$,所以这个结论显然成立。 所以 $a^b\equiv a^{\varphi(p)+b}\pmod p$。 这就可以证明 $n$ 为质数的幂次方时的情况。剩余的用唯一分解定理即可简单证明。 [模板](https://www.luogu.com.cn/problem/P5091) ``` #include <bits/stdc++.h> using namespace std; #define int long long template<class T>T Pow(T a,T b,T p,T ans=1){for(;b;b/=2){ans=((b&1?a:1)*ans%p),a=a*a%p;}return ans;} int a,b,m,v; inline int Read() { int x = 0,f = 0; char c = getchar(); for(;c < '0' || c > '9';c = getchar()); for(;c >= '0' && c <= '9';c = getchar()) { x = (x << 3) + (x << 1) + (c ^ 48); if(x >= v) f = 1; x %= v; } return f ? x + v : x; } int GetPhi(int n) { int ans = n; for(int i = 2;i * i <= n;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; } signed main() { cin >> a >> m; v = GetPhi(m); b = Read(); if(b < v) cout << Pow(a,b,m) << '\n'; else cout << Pow(a,b % v + v,m) << '\n'; return 0; } ```