题目:http://acm.hdu.edu.cn/showproblem.php?pid=2837
Calculation
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
Sample Output
16 5
思路: A^x = A^(x % Phi(C) + Phi(C)) (mod C) 当x>c时才执行,此题在递归过程中在反复的判断这个条件。
#include<stdio.h>
typedef __int64 LL;
LL euler(LL m) //欧拉函数
{
LL i,ans=m;
if(m%2==0)
{
ans=ans-ans/2;
while(m%2==0)
m/=2;
}
for(i=3;i*i<=m;i+=2)
{
if(m%i==0)
{
ans=ans-ans/i;
while(m%i==0)
m/=i;
}
}
if(m>1)ans=ans-ans/m;
return ans;
}
LL f(LL n,LL m)
{
if(n==0)return 1;
LL a=n%10;
LL c=euler(m);
LL b=f(n/10,c);
LL k=1;
LL bb=b;
LL flag=0;
for(LL i=0;i<b;i++) //判断“思路”中所说的是否满足“x>c”。这里只能一个个的乘a,不能用快速幂的方式来判断,会溢出。
{
k*=a;
if(k>m)
{
flag=1;
break;
}
}
if(flag==0)return k;
k=1;
b=bb;
if(b>c)b=b%c+c;
while(b)
{
if(b&1)
k=k*a%m;
a=a*a%m;
b>>=1;
}
return k+m; //这里卡了很久,总是忘了加上m。
}
int main()
{
LL t,n,i,j,m;
scanf("%I64d",&t);
while(t--)
{
scanf("%I64d%I64d",&n,&m);
printf("%I64d\n",f(n,m)%m);
}
return 0;
}