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}