首页 > 代码库 > hdu5728

hdu5728

详细题解:

http://blog.csdn.net/wust_zzwh/article/details/51966450

……化简公式的能力还不够啊……

技术分享
 1 #include<bits/stdc++.h>
 2 
 3 using namespace std;
 4 typedef long long ll;
 5 const int mo=1e9+7;
 6 const int mx=1e7;
 7 bool v[mx+5];
 8 int pr[mx+5],phi[mx+5],s[mx+5],a[100010],r,n,m,t,p;
 9 
10 void resolve(int n)
11 {
12     r=0;
13     for (int i=1; i<=t; i++)
14         if (n%pr[i]==0) {a[++r]=pr[i]; n/=pr[i];}
15         else if (n<pr[i]) break;
16 }
17 
18 int quick(ll x,ll y,int p)
19 {
20     ll s=1;
21     while (y)
22     {
23         if (y&1) s=s*x%p;
24         x=x*x%p;
25         y>>=1;
26     }
27     return (s==0)?p:s;
28 }
29 
30 ll f(int i,int n,int m)
31 {
32     if (n==1) return s[m];
33     if (m==0) return 0;
34     return (1ll*(a[i]-1)*f(i+1,n/a[i],m)%mo+f(i,n,m/a[i]))%mo;
35 }
36 
37 int ans(int k,int p)
38 {
39     if (p==1) return 1;
40     return quick(k,ans(k,phi[p]),p);
41 }
42 
43 int main()
44 {
45     phi[1]=1;
46     for (int i=2; i<=mx; i++)
47     {
48         if (!v[i])
49         {
50             pr[++t]=i;
51             v[i]=1;
52             phi[i]=i-1;
53         }
54         for (int j=1; j<=t; j++)
55         {
56             if (i*pr[j]>mx) break;
57             v[i*pr[j]]=1;
58             if (i%pr[j]) phi[i*pr[j]]=phi[i]*(pr[j]-1);
59             else {
60                 phi[i*pr[j]]=phi[i]*pr[j];
61                 break;
62             }
63         }
64     }
65     for (int i=1; i<=mx; i++) s[i]=(s[i-1]+phi[i])%mo;
66     while (scanf("%d%d%d",&n,&m,&p)!=EOF)
67     {
68         if (p==1) {puts("0"); continue;}
69         resolve(n);
70         ll k=f(1,n,m);
71         printf("%d\n",ans(k,p)%p);
72     }
73 }
View Code

 

hdu5728