|
CalculationTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1912 Accepted Submission(s): 413 链接:click me
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
Sample Output
|
题意:
已知f(0) = 1,0^0 =1,【注意,0的其他任意次方为0,虽然题没有直接给出~】,还已知f(n) = (n%10)^f(n/10),让你求f(n)%m. (2 ≤ n , m ≤ 10^9)
分析:
求解一个递归式,f(n)递归下去是需要多次求幂的,这样,我们就可以用指数循环节来降幂处理,公式如下图,phi(i)表示的i的欧拉函数值,其实指数循环节就是欧拉函数+快速幂的一个结合而已,在这个题里面需要特别注意的就是对0的处理,求0的多次方需要进行判断一下。
还有一种降幂的方法在我另外一篇博客上有详细的讲解,请参考《2015 CSUST校赛 - 超级快速幂【费马小定理】+【快速幂取模】》,追根溯源,其实费小马定理就是欧拉定理的一个拓展~,更多数论知识,请参考《数论基础的补充讲解》~
实现代码:
#include <set>
#include <cmath>
#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define FIN freopen("input.txt","r",stdin)
#define FOUT freopen("output.txt","w",stdout)
#define CASE(T) for(scanf("%d",&T);T--;)
typedef __int64 LL;
int T;
LL N, M, P;
LL phi(LL n)
{
LL ans = n;
for(LL i = 2; i * i <= n; i++)
{
if(n % i == 0)
{
ans -= ans / i ;
while(n % i == 0) n /= i;
}
}
if(n > 1) ans -= ans / n ;
return ans;
}
//迭代形式
//LL pow_mod(LL a, LL p, LL mod)
//{
// LL ans = 1;
// if(a == 0) return p == 0;
// while(p)
// {
// if(p & 1)
// {
// ans = ans * a % mod;
// if(ans == 0) ans = mod;
// }
// a = a * a % mod;
// p >>= 1;
// }
// return ans;
//}
LL pow_mod(LL a, LL b, LL MOD)
{
if(b == 0) return 1;
if(a == 0) return 0;
LL x, ans;
x = pow_mod(a, b >> 1, MOD);
ans = x * x % MOD;
if(b & 1) ans = (a * ans) % MOD;
if(ans == 0) ans = MOD;
return ans;
}
LL f(int n,int m)
{
if(n < 10) return n;
int x = f(n / 10,phi(m)),ans;
ans = pow_mod(n % 10,x,m);
return ans;
}
int main()
{
#ifndef ONLINE_JUDGE
FIN;
#endif // ONLINE_JUDGE
CASE(T)
{
scanf("%I64d %I64d", &N, &M);
LL ans = f(N,M);
printf("%I64d\n", ans % M);
}
return 0;
}