欢迎关注__Xiong的博客: http://blog.csdn.net/acmore_xiong?viewmode=list |
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 2 24 20 25 20 Sample Output 16 5 |
题意:
已知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; }
版权声明:本文为博主原创文章,未经博主允许不得转载。