hdu 2837 Calculation (指数循环节+欧拉函数)
题意:
Assume that f(0) = 1 and 0^0=1. f(n) = (n)^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).
思路:指数循环节。
trick点在于0^0=1这点。
比较容易想到的一层是ksm的时候特判。
比较不容易想到的一层是,0作为底数的时候,可能出现0^a在用降幂公式加速后,出现0^0。
举个例子:
680 80
phi(80)=32,恰好是8^6的因子
而0^(8^6)答案应该为0,用降幂公式加速后变成了0^0,答案变成了1,结果错误
究其原因,是因为这道题中底数可能有0以及0^0是题目中定义的运算。
解决办法是ksm的结果判断一下,如果是0就加mod。
1/* ***********************************************
2Author :111qqz
3Created Time :Sun 30 Oct 2016 07:19:02 PM CST
4File Name :code/hdu/2837.cpp
5************************************************ */
6#include <cstdio>
7#include <cstring>
8#include <iostream>
9#include <algorithm>
10#include <vector>
11#include <queue>
12#include <set>
13#include <map>
14#include <string>
15#include <cmath>
16#include <cstdlib>
17#include <ctime>
18#define fst first
19#define sec second
20#define lson l,m,rt<<1
21#define rson m+1,r,rt<<1|1
22#define ms(a,x) memset(a,x,sizeof(a))
23typedef long long LL;
24#define pi pair < int ,int >
25#define MP make_pair
26using namespace std;
27const double eps = 1E-8;
28const int dx4[4]={1,0,0,-1};
29const int dy4[4]={0,-1,1,0};
30const int inf = 0x3f3f3f3f;
31LL n,m;
32LL digit[20];
33int cnt;
34LL ksm( LL a,LL b,LL mod)
35{
36 // cout<<"a:"<<a<<" b:"<<b<<" mod:"<<mod<<" ";
37 if (b==0) return 1;
38 if (a==0) return 0; //任何数的0次方都为1,0的任何除0外次方等于0.
39 LL res = 1;
40 while (b>0)
41 {
42 if (b&1) res = ( res * a) % mod;
43 b = b >> 1LL;
44 a = ( a*a) % mod;
45 }
46 // if (res<mod) res = res+mod;
47 if (res==0) res = mod;
48 // cout<<" res:"<<res<<endl;
49 return res;
50}
51LL euler( LL x)
52{
53 LL ret = 1;
54 for ( LL i =2 ; i * i <= x ; i++)
55 {
56 if (x%i==0)
57 {
58 x/=i;
59 ret*=(i-1);
60 while (x%i==0)
61 {
62 x/=i;
63 ret*=i;
64 }
65 }
66 }
67 if (x>1) ret*=(x-1);
68 return ret;
69}
70LL fun( LL n,LL m)
71{
72 if (n<10) return n;
73 LL x = fun(n/10,euler(m));
74 // cout<<"n:"<<n<<" m:"<<m<<" x:"<<x<<endl;
75 if (x>=euler(m)) x = x%euler(m) + euler(m);
76 return ksm(n,x,m);
77}
78int main()
79{
80 #ifndef ONLINE_JUDGE
81// freopen("code/in.txt","r",stdin);
82 #endif
83 int T;
84 cin>>T;
85 while (T--)
86 {
87 scanf("%lld%lld",&n,&m);
88 printf("%lld\n",fun(n,m)%m);
89 }
90 #ifndef ONLINE_JUDGE
91 fclose(stdin);
92 #endif
93 return 0;
94}