题目大意:
题目链接:https://www.luogu.org/problem/P5091
求
a
b
m
o
d
  
m
a^b\mod m
abmodm。
思路:
扩展欧拉定理的模板题。
具体还不会证明。证明就出门右转题解区吧。
欧拉定理:对于任意的
a
,
p
∈
Z
∗
a,p\in \Z^*
a,p∈Z∗,若满足
(
a
,
b
)
=
1
(a,b)=1
(a,b)=1,那么必然就有
a
φ
(
m
)
≡
1
(
m
o
d
p
)
a^{\varphi(m)} \equiv 1(mod\ p)
aφ(m)≡1(mod p)
扩展欧拉定理:当
p
≥
φ
(
m
)
p\geq \varphi(m)
p≥φ(m)时,必有
a
p
≡
a
p
m
o
d
φ
(
m
)
+
φ
(
m
)
(
m
o
d
p
)
a^p\equiv a^{p\ mod\ \varphi(m)+\varphi(m)}(mod\ p)
ap≡ap mod φ(m)+φ(m)(mod p)
所以就算出
φ
(
p
)
\varphi(p)
φ(p),然后从高位到低位依次读入
b
b
b的每一位,同时取模
φ
(
m
)
\varphi(m)
φ(m)。然后由于最终的指数不会超过
1
0
6
10^6
106,所以直接暴力乘上去就可以了。
注意只有在
b
>
φ
(
m
)
b>\varphi(m)
b>φ(m)时指数才需要在最后加
φ
(
m
)
\varphi(m)
φ(m)。
代码:
#include <cstdio>
using namespace std;
typedef long long ll;
ll a,b,p,q,phi;
bool flag;
int main()
{
scanf("%lld%lld",&a,&p);
phi=q=p;
for (ll i=2;i*i<=q;i++)
if (!(q%i))
{
phi=phi/i*(i-1);
while (!(q%i)) q/=i;
}
if (q>1) phi=phi/q*(q-1);
while (scanf("%1lld",&q)==1)
{
b=b*10+q;
if (b>=phi) flag=1;
b%=phi;
}
if (flag) b+=phi;
for (ll i=1,x=a;i<b;i++)
a=a*x%p;
printf("%lld\n",a);
return 0;
}