题目链接http://acm.hdu.edu.cn/showproblem.php?pid=4549;
题目是中文的很容易理解吧。可一开始我把题目看错了,这毛病哈哈。 一开始我看错题时,就用了一个快速幂来解,不用说肯定wa,看题目的通过率也不高,我想会不会有啥坑啊。然而我就是那大坑,哈哈。
不说了,直接说题吧,先讨论k=1,2,3;时的解。这应该会解吧,不多说了;
从第四项开始f(4)=a^1+b^2;f(5)=a^2+b^3;f(6)=a^3+b^5......; 看出来了吧,a上的指数成斐波那契数列,b的也成,而且a的指数是b的前一项;
那么就打表求斐波那契数列呗,不敢,范围太大,又爆内存又超时的。
f(n)=a^k(n-4)+b^k(n-3);其中n>=4;k(0)=1;k(1)=2;
用矩阵来求斐波那契数列的相邻两项有[k[n-2],k[n-1]]*[0 1]
[1 1]
上式等于[k[n-1],k[n]];
那么要求[k[n-4],k[n-3]]=[1,2]*[0 1]^(n-3)
[1 1]
这样就可以用矩阵快速幂来求k[n-4],k[n-3]了;
但光这样还不够,在矩阵快速幂过程中还得取模,不然会溢出。
由费马小定理在p为素数的情况下对任意的整数x都有x^p==x(mod p)
;如果x不能被p整除有x^(p-1)=1(mod p);由于a,b<1e9;所以不能被1e9+7整除, 求出了k[n],则a^k[n]%p=a^(k[n]%(p-1))%p;
证明如下: k[n]=m*(p-1)+d;那么a^k[n]%p=a^[(m*(p-1))+d]%p=(a^[m*(p-1)]%p*a^(d)%p)%p;
由费马小定理可知a^(m*(p-1))%p=1; 而d=k[n]%(p-1);得证;
所以矩阵快速幂时要对1e+6取模就行了; 当k(n)求出来是再进行快速幂运算就可以了,复杂度为2*log2(n); 注意要开longlong不然会溢出。
下面看代码:
1 #include<stdio.h> 2 #include<string.h> 3 #include<iostream> 4 #include<algorithm> 5 #include<stdlib.h> 6 #include<math.h> 7 const long long N=1e9+7; 8 const long long M=1e9+6; 9 typedef long long ll; 10 void kk(ll y); 11 ll pp(ll x,ll y); 12 ll b[2][2]; 13 ll a[2][2]; 14 using namespace std; 15 int main(void) 16 { 17 ll i,j,k,p,q,n,m; 18 19 while(scanf("%lld%lld%lld",&p,&q,&k)!=EOF) 20 { 21 if(k==0) 22 { 23 printf("%lld\n",p%N); 24 25 } 26 else if(k==1) 27 { 28 printf("%lld\n",q%N); 29 30 } 31 else if(k==2) 32 { 33 printf("%lld\n",(p%N*q%N)%N); 34 } 35 else 36 { 37 k=k-3; 38 kk(k); 39 ll p1=(b[0][0]%M+2*b[1][0]%M)%M;//求的k(n-4) 40 ll p2=(b[0][1]%M+2*b[1][1]%M)%M;//k[n-3] 41 ll x1=pp(p,p1);//a^k(n-4); 42 ll x2=pp(q,p2);//b^k(n-3); 43 ll dd=(x1*x2)%N;//d=(a^k(n-4)*b^k(n-3))%N; 44 printf("%lld\n",dd); 45 46 } 47 48 } 49 50 return 0; 51 52 } 53 54 ll pp(ll x,ll y)//快速幂 55 { 56 ll p=x; 57 ll q=1; 58 59 while(y) 60 { 61 if(y&1) 62 { 63 q=(q%N*p%N)%N; 64 } 65 p=(p%N*p%N)%N; 66 67 y=y/2; 68 } 69 return q; 70 71 } 72 73 74 void kk(ll y)//矩阵快速幂 形式和快速幂基本一样。 75 { 76 ll i,j,k; 77 ll x1,x2,x3,x4; 78 a[0][0]=0;//a为变换矩阵; 79 a[0][1]=1; 80 a[1][0]=1; 81 a[1][1]=1; 82 b[0][0]=1;//b为单位阵; 83 b[0][1]=0; 84 b[1][0]=0; 85 b[1][1]=1; 86 87 while(y) 88 { 89 if(y&1) 90 { 91 x1=((b[0][0]*a[0][0])%M+(b[0][1]*a[1][0])%M)%M; 92 x2=((b[0][0]*a[0][1])%M+(b[0][1]*a[1][1])%M)%M; 93 x3=((b[1][0]*a[0][0])%M+(b[1][1]*a[1][0])%M)%M; 94 x4=((b[1][0]*a[0][1])%M+(b[1][1]*a[1][1])%M)%M; 95 b[0][0]= x1; 96 b[0][1]=x2; 97 b[1][0]=x3; 98 b[1][1]=x4; 99 } 100 x1=((a[0][0]*a[0][0])%M+(a[0][1]*a[1][0])%M)%M; 101 x2=((a[0][0]*a[0][1])%M+(a[0][1]*a[1][1])%M)%M; 102 x3=((a[1][0]*a[0][0])%M+(a[1][1]*a[1][0])%M)%M; 103 x4=((a[1][0]*a[0][1])%M+(a[1][1]*a[1][1])%M)%M; 104 a[0][0]=x1; 105 a[0][1]=x2; 106 a[1][0]=x3; 107 a[1][1]=x4; 108 y/=2; 109 110 } 111 112 113 114 115 }