hdu 4335 What is N?

此题用到的公式:a^b%c=a^(b%phi(c)+phi(c))%c (b>=phi(c)).

1.当n!<phi(p)时,直接暴力掉;

2.当n!>=phi(p) && n!%phi(p)!=0,用上面公式求;

3.当n!>=phi(p) && n!%phi(p)==0,变为n^(phi(p))%p,找循环节,就可以了

 

 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<algorithm>
 4 #include<iomanip>
 5 #include<cmath>
 6 #include<string>
 7 #include<cstdlib>
 8 #include<vector>
 9 #define ll unsigned __int64
10 using namespace std;
11 ll an[100001];
12 ll euler(ll n)
13 {
14     ll ans=1;
15     for(int i=2;i*i<=n;i++)
16     {
17         if(n%i==0)
18         {
19             ans*=i-1;
20             n/=i;
21             while(n%i==0)
22             {
23                 ans*=i;
24                 n/=i;
25             }
26         }
27     }
28     if(n>1) ans*=n-1;
29     return ans;
30 }
31 ll pows(ll a,ll b, ll mod)
32 {
33     ll ans=1;
34     while(b)
35     {
36         if(b&1) ans=(ans*a)%mod;
37         b>>=1;
38         a=(a*a)%mod;
39     }
40     return ans%mod;
41 }
42 int main()
43 {
44     int t,k=0;
45     ll m,ans,fac,c,i,j,phi,b,p;
46     cin>>t;
47     while(t--)
48     {
49         scanf("%I64u%I64u%I64u",&b,&p,&m);
50         printf("Case #%d: ",++k);
51         if(p==1)
52         {
53             if(m==18446744073709551615U)  
54                printf("18446744073709551616\n");    
55             else printf("%I64u\n",m+1);
56             continue;
57         }
58         ans=0;fac=1;
59         phi=euler(p);
60         //n!<phi(p)
61         for(i=0;i<=m&&fac<=phi;i++)
62         {
63             if(pows(i,fac,p)==b)
64                 ans++;
65             fac*=(i+1);
66         }
67         fac%=phi;
68         //n!>=phi(p) && n!%phi(p)!=0
69         for(;i<=m&&fac;i++)
70         {
71             if(pows(i,fac+phi,p)==b)
72                 ans++;
73             fac=(fac*(i+1))%phi;
74         }
75         //n!>=phi(p) && n!%phi(p)==0
76         if(i<=m)
77         {
78             ll cnt=0;
79         //    memset(an,0,sizeof(an));
80             for(j=0;j<p;j++)
81             {
82                 an[j]=pows(i+j,phi,p);
83                 if(an[j]==b)
84                     cnt++;
85             }
86             c=(m-i+1)/p;
87             ans+=c*cnt;
88             ll remind=(m-i+1)%p;
89             for(j=0;j<remind;j++)
90                 if(an[j]==b)
91                     ans++;
92         }
93         printf("%I64u\n",ans);
94     }
95     return 0;
96 }
View Code

 

 

 

posted @ 2013-07-22 17:14  _随心所欲_  阅读(142)  评论(0编辑  收藏  举报