FZU 1759 Super A^B mod C(欧拉降幂 )
解题思路
欧拉降幂的模板题,因为C与A不一定互质,所以这里要用到广义欧拉降幂,用广义欧拉降幂的时候记得讨论指数与模数的大小关系。
线性筛选素数
bool u[maxn];
int p[maxn]; char b[maxn];
void pri() {
for (int i = 2; i<maxn; ++i) {
if (!u[i]) u[i] = p[++p[0]] = i;
for (int j = 1; i*p[j]<maxn; ++j) {
u[i*p[j]] = true;
if (i%p[j]==0) break;
}
}
}
快速幂
ll solve(ll x, ll y, ll m) {
ll res = x, ans = 1;
while(y) {
if (y&1) ans = ans*res%m;
res = res*res%m;
y >>= 1;
}
return ans;
}
如果指数小于模数的欧拉函数,则直接用快速幂求出答案。
for (int i = 0; i<len; ++i) numb = numb*10 + b[i]-'0';
printf("%lld\n", solve(a, numb, c));
否则,求模数的欧拉函数并且进行降幂,然后快速幂求解
ll phi(ll num) {
ll res = num;
for (int i = 1; (ll)p[i]*p[i]<=num && i<=p[0]; ++i)
if (num%p[i]==0) {
while(num%p[i]==0) num /= p[i];
res = res/p[i]*(p[i]-1);
}
if (num>1) res = res/num*(num-1);
return res;
}
ll phic = phi(c);
for (int i = 0; i<len; ++i) numb = (numb*10 + b[i]-'0')%phic;
printf("%lld\n", solve(a, numb+phic, c));
完整代码
const int maxn = 1e6+10;
bool u[maxn];
int p[maxn]; char b[maxn];
void pri() {
for (int i = 2; i<maxn; ++i) {
if (!u[i]) u[i] = p[++p[0]] = i;
for (int j = 1; i*p[j]<maxn; ++j) {
u[i*p[j]] = true;
if (i%p[j]==0) break;
}
}
}
ll phi(ll num) {
ll res = num;
for (int i = 1; (ll)p[i]*p[i]<=num && i<=p[0]; ++i)
if (num%p[i]==0) {
while(num%p[i]==0) num /= p[i];
res = res/p[i]*(p[i]-1);
}
if (num>1) res = res/num*(num-1);
return res;
}
ll solve(ll x, ll y, ll m) {
ll res = x, ans = 1;
while(y) {
if (y&1) ans = ans*res%m;
res = res*res%m;
y >>= 1;
}
return ans;
}
int main(){
pri(); ll a, c;
while(~scanf("%lld%s%lld", &a, b, &c)) {
int len = strlen(b); ll numb = 0;
if (len>10) {
ll phic = phi(c);
for (int i = 0; i<len; ++i) numb = (numb*10 + b[i]-'0')%phic;
printf("%lld\n", solve(a, numb+phic, c));
}
else {
for (int i = 0; i<len; ++i) numb = numb*10 + b[i]-'0';
printf("%lld\n", solve(a, numb, c));
}
}
return 0;
}