Calculation
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2272 Accepted Submission(s): 536
Problem Description
Assume that f(0) = 1 and 0^0=1. f(n) = (n%10)^f(n/10) for all n bigger than zero. Please calculate f(n)%m. (2 ≤ n , m ≤ 10^9, x^y means the y th power of x).
Input
The first line contains a single positive integer T. which is the number of test cases. T lines follows.Each case consists of one line containing two positive integers n and m.
Output
One integer indicating the value of f(n)%m.
Sample Input
2
24 20
25 20
24 20
25 20
Sample Output
16
5
5
题意:求解$f(n) = {(n\%10)}^{f(n/10)}\%m $,其中$(2 <= n, m <= 10^9)$;
思路:一看到指数模除,并且没有说明是否互素,直接上指数循环节,化简指数==套路...
注:
1. 使用指数循环节都是递归形式,所以欧拉函数也需要是递归形式;
2. 在指数循环节中的快速幂时,需要在ans >= mod时,模完之后还要加上mod;
#include <iostream>
#include<cstdio>
using namespace std;
#define ll long long
ll phi(ll c)
{
ll ans = c;
for(int i = ; i*i <= c; i++) {
if(c%i == ){
ans -= ans/i;
while(c%i == ) c /= i;
}
}
if(c > ) ans -= ans/c;
return ans;
}
ll quick_mod(ll a, ll b, ll mod)
{
if(a >= mod) a = a%mod + mod; // 并不是直接%mod
ll ans = ;
while(b){
if(b&){
ans = ans*a;
if(ans >= mod) ans = ans%mod + mod; //**
}
a *= a;
if(a >= mod) a = a%mod + mod; //**
b >>= ;
}
return ans;
}
ll solve(ll n, ll m)
{
ll p = phi(m);
if(n == ) return ;
ll index = solve(n/, p); return quick_mod(n%, index, m);
}
int main()
{
ll n, m, T;
cin >> T;
while(T--){
scanf("%I64d%I64d", &n, &m);
printf("%I64d\n", solve(n,m)%m);
}
return ;
}