给出两个公式:
a^b%c=a^(b%phi(c)). 欧拉函数降幂,要求a与c互质
a^b %c= a^(b%phi(c)+phi(c)) %c (b>=phi(c),不大于时直接二分幂) 扩展的欧拉函数用于降幂,无互质要求
CODE:
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e6+10;
LL c;
char b[N]; ///b
char s[N]; ///n
LL euler_phi(LL n){ ///计算单个phi函数
LL m = (int)sqrt(n+0.5);
LL ans = n;
for(LL i = 2;i <= m;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;
}
LL Pow(LL a,LL b,LL mod){ ///二分幂
LL ret = 1;
LL A = a;
while(b){
if(b&1) ret = ret*A%mod;
A = A*A%mod;
b >>= 1;
}
return ret;
}
int main(void)
{
scanf("%s%s%I64d",b,s,&c);
int lenb = strlen(b);
int lens = strlen(s);
LL tb=0,tb1=0; ///b和b-1
for(int i = 0;i < lenb;i++){ ///计算b
tb = (tb*10+b[i]-'0')%c;
}
tb1 = (tb-1+c)%c; ///计算b-1
LL phic = euler_phi(c);
for(int i = lens-1;i >= 0;i--){ ///n-1
if(s[i] == 0) s[i] = '9';
else{
s[i]--;
break;
}
}
bool flag = false; ///标记n是否大于等于phic
LL tn = 0; ///n
for(int i = 0;i < lens;i++){ ///计算n
if(tn >= phic) flag = true;
if(flag) tn = (tn*10+s[i]-'0')%phic;
else tn = tn*10+s[i]-'0';
}
if(flag) tn += phic; ///n大于等于phic的时候才加
LL ans = Pow(tb,tn,c);
ans = ans*tb1%c;
if(ans == 0) printf("%I64d\n",c);
else printf("%I64d\n",ans);
return 0;
}