题意:
给出
a
,
b
,
m
(
1
≤
a
≤
1
0
9
,
1
≤
b
≤
1
0
20000000
,
1
≤
m
≤
1
0
8
)
a,b,m(1\leq a \leq 10^9,1 \leq b \leq 10^{20000000 },1 \leq m \leq 10^8)
a,b,m(1≤a≤109,1≤b≤1020000000,1≤m≤108)求:
a
b
a^b
ab%
m
m
m
题解:
什么叫欧拉降幂??这种题就用欧拉降幂,幂数太大!!!必须要把b用某种方法降下来,这种方法就是欧拉降幂!!
这就是欧拉公式了
对于这道题而言,我们只需要找到
m
o
d
mod
mod的欧拉函数和
b
b
b的相对大小就可以了。此前我已经细讲了欧拉函数打表欧拉,不了解的可以翻一翻我之前的博客,另外,这题的模数是10的8次方,开空间是开不下的,需要取巧求一下欧拉函数
code:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1e4+5;
int prime[maxn/10],phi[maxn],tot,mod,pmod=1;
void Euler(){
phi[1]=1;
for(int i=2;i<maxn;i++){
if(!phi[i]){
phi[i]=i-1;
prime[tot++]=i;
}
for(int j=0;j<tot&&prime[j]*i<maxn;j++){
if(i%prime[j]==0){
phi[i*prime[j]]=phi[i]*prime[j];
break;
}
phi[i*prime[j]]=phi[i]*(prime[j]-1);
}
}
int smod=mod;
for(int i=0;prime[i]*prime[i]<=smod;i++){
if(smod%prime[i]==0){
smod/=prime[i];
pmod*=(prime[i]-1);
while(smod%prime[i]==0)pmod*=prime[i],smod/=prime[i];
}
}
if(smod!=1)pmod*=(smod-1);
}
ll fast(ll x,ll y){
ll ans=1;
while(y){
if(y&1)ans=ans*x%mod;
x=x*x%mod;
y>>=1;
}
return ans;
}
inline ll read(bool &f){
ll x=0;char ch=getchar();
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))
x=(x<<1)+(x<<3)+(ch^48),f|=x>=pmod,x%=pmod,ch=getchar();
return x;
}
int main(){
ll a;
bool flag=false;
cin>>a>>mod;
Euler();
ll b=read(flag);
if(__gcd(a,mod*1ll)!=1&&flag)b+=pmod;
cout<<fast(a,b);
return 0;
}