hdu 2481 Toy

好题!!!没话说……

用到的知识面很多,这题的难点在于公式的推导。

原始推导过程见:http://hi.baidu.com/spellbreaker/item/d8bb3bda5af30be6795daa93

这个过程有点小问题,改进后的见:http://blog.csdn.net/acm_cxlove/article/details/7868589

下面是自己敲的代码:

 

 1 /*************************************************************************  2  > File Name: xh.cpp  3  > Author: XINHUA  4  > Mail: [email protected]  5  > Created Time: 2013/7/19 星期五 15:11:25 新华  6  ************************************************************************/

 7 

 8 #include<iostream>

 9 #include<stdio.h>

 10 #include<algorithm>

 11 #include<iomanip>

 12 #include<cmath>

 13 #include<string>

 14 #include<vector>

 15 using namespace std;  16 int prime[30001],m,n;  17 bool f[30001]={0};  18 __int64 mod;  19 struct ma  20 {  21     __int64 a[2][2];  22     void init()  23  {  24         a[0][0]=a[1][1]=1;  25         a[0][1]=a[1][0]=0;  26  }  27 }e;  28 //使用二分模拟乘法计算(a和b的范围太大)

 29 __int64 mulmod(__int64 a,__int64 b)  30 {  31     a%=mod;b%=mod;  32     if(a<0) a+=mod;  33     if(b<0) b+=mod;  34     __int64 ans=0;  35     while(b)  36  {  37         if(b&1)  38  {  39             ans+=a;  40             if(ans>=mod) ans-=mod;  41  }  42         a=a<<1;  43         if(a>=mod) a-=mod;  44         b=b>>1;  45  }  46     return  ans%mod;  47 }  48 ma operator*(ma ab,ma b)  49 {  50  ma ans;  51     int i,j,k;  52     for(i=0;i<2;i++)  53  {  54         for(j=0;j<2;j++)  55  {  56             ans.a[i][j]=0;  57             for(k=0;k<2;k++)  58                 ans.a[i][j]=(ans.a[i][j]+mulmod(ab.a[i][k],b.a[k][j]))%mod;  59  }  60  }  61     return ans;  62 }  63 ma operator^(ma ab,int b)  64 {  65  ma ans;  66  ans.init();  67     while(b)  68  {  69         if(b&1) ans=ans*ab;  70         b>>=1;  71         ab=ab*ab;  72  }  73     return ans;  74 }  75 

 76 void init_prime()  77 {  78     int i,j;  79     m=0;  80     for(i=2;i<=30000;i++)  81  {  82         if(f[i]==0) prime[m++]=i;  83         for(j=0;j<m&&i*prime[j]<=30000;j++)  84  {  85             f[i*prime[j]]=1;  86             if(i%prime[j]==0) break;  87  }  88  }  89 }  90 __int64 euler(__int64 n)  91 {  92     __int64 ans=1;  93     for(int i=0;i<m&&prime[i]*prime[i]<=n;i++)  94  {  95         if(n%prime[i]==0)  96  {  97             ans*=prime[i]-1;  98             n/=prime[i];  99             while(n%prime[i]==0) 100  { 101                 n/=prime[i]; 102                 ans=(ans*prime[i])%mod; 103  } 104  } 105  } 106     if(n>1) ans*=n-1; 107     return ans%mod; 108 } 109 __int64 get_T(int k) 110 { 111     if(k==1) return 1; 112     else if(k==2) return 5; 113     ma temp=e^(k-2); 114     __int64 f=3*temp.a[0][0]+temp.a[1][0]; 115     __int64 g=2*(f-(3*temp.a[0][1]+temp.a[1][1])-1); 116     return (f+g)%mod; 117 } 118 int main() 119 { 120  init_prime(); 121     e.a[0][0]=3;e.a[0][1]=1;e.a[1][0]=-1;e.a[1][1]=0; 122     while(scanf("%d%I64d",&n,&mod)!=EOF) 123  { 124         mod=(__int64)n*mod; 125         __int64 sum=0; 126         for(int i=1;i*i<=n;i++) 127  { 128             if(n%i==0) 129  { 130                 sum=(sum+mulmod(euler(i),get_T(n/i)))%mod; 131                 if(i*i!=n) 132                     sum=(sum+mulmod(euler(n/i),get_T(i)))%mod; 133  } 134  } 135         sum/=n; 136         printf("%I64d\n",sum%(mod/n)); 137  } 138     return 0; 139 }
View Code

 

 

 

你可能感兴趣的:(HDU)