欧拉定理
若正整数
a
,
n
a,n
a,n互质,则 (其中
φ
(
n
)
{\varphi(n)}
φ(n)为欧拉函数)
a
b
≡
a
b
m
o
d
φ
(
n
)
(
m
o
d
n
)
a^{b} \equiv a^{b\ mod\ \varphi(n)}(mod\ n)
ab≡ab mod φ(n)(mod n)
由此得到降幂公式:
a
b
≡
{
a
b
m
o
d
φ
(
p
)
gcd
(
a
,
p
)
=
1
a
b
gcd
(
a
,
p
)
=
̸
1
,
b
<
φ
(
p
)
(
m
o
d
p
)
a
b
m
o
d
φ
(
p
)
+
φ
(
p
)
gcd
(
a
,
p
)
=
̸
1
,
b
≥
φ
(
p
)
a^b \equiv\begin{cases} a^{b\ mod\ \varphi(p)}\ \ \ \ \ \ \ \ \ \ \gcd(a,p)=1 \\ a^{b}\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \gcd(a,p)=\not1,b < \varphi(p)\ \ \ \ (mod\ p) \\ a^{b\ mod\ \varphi(p)+\varphi(p)}\ \ \gcd(a,p)=\not1,b\geq \varphi(p) \end{cases}
ab≡⎩⎪⎨⎪⎧ab mod φ(p) gcd(a,p)=1ab gcd(a,p)≠1,b<φ(p) (mod p)ab mod φ(p)+φ(p) gcd(a,p)≠1,b≥φ(p)
【例题1】BZOJ 3884
题意:
求 2 2 2 . . . ∞ 2^{2^{2^{...\infty}}} 222...∞无限个2的次方的值。
思路
直接用快速幂是不可能的,正解是使用欧拉降幂进行求解,使用递归。
设
f
(
p
)
f(p)
f(p)是一个正确答案。
从化简的第三步可以看出这个递归的过程:
f
(
p
)
=
2
f
(
φ
(
p
)
)
+
φ
(
p
)
m
o
d
p
f(p)=2^{f(\varphi(p))+\varphi(p)}\ mod\ p
f(p)=2f(φ(p))+φ(p) mod p
递归基是当模数
p
p
p 为 1 的时候,返回0。
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <string>
#define ll long long
using namespace std;
//返回欧拉函数
ll getphi(ll n){
ll res = n;
for(ll i = 2ll; i <= sqrt(n); i++){
if(n % i == 0){
res = res / i * (i - 1);
while(n % i == 0) n /= i;
}
}
if(n > 1) res = res / n * (n - 1);
return res;
}
ll qpow(ll a,ll b ,ll mod){
ll res = 1ll;
while(b){
if(b & 1) res = res * a % mod;
a = a * a % mod;
b >>= 1;
}
return res;
}
ll solve(ll p){
if(p == 1)
return 0;
ll phi=getphi(p);
return qpow(2ll,solve(phi)+phi,p);
}
int main(){
ll cas,p,n;
scanf("%lld",&cas);
while(cas--){
scanf("%lld",&p);
printf("%lld\n",solve(p));
}
return 0;
}
【例题2】2019 ICPC南京网络赛 B - Super_log
南京网赛使我继多校后再次自闭