M斐波那契数列
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)
Total Submission(s): 1672 Accepted Submission(s): 482
Problem Description
M斐波那契数列F[n]是一种整数数列,它的定义如下:
F[0] = a
F[1] = b
F[n] = F[n-1] * F[n-2] ( n > 1 )
现在给出a, b, n,你能求出F[n]的值吗?
F[0] = a
F[1] = b
F[n] = F[n-1] * F[n-2] ( n > 1 )
现在给出a, b, n,你能求出F[n]的值吗?
Input
输入包含多组测试数据;
每组数据占一行,包含3个整数a, b, n( 0 <= a, b, n <= 10^9 )
每组数据占一行,包含3个整数a, b, n( 0 <= a, b, n <= 10^9 )
Output
对每组测试数据请输出一个整数F[n],由于F[n]可能很大,你只需输出F[n]对1000000007取模后的值即可,每组数据输出一行。
Sample Input
0 1 0
6 10 2
Sample Output
0
60
Source
题意:不解释,中文题。
思路:费马小定理+矩阵快速幂
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4549
转载请注明出处:寻找&星空の孩子
#include<cstring> #include<cstdio> #include<iostream> #include<algorithm> using namespace std; #define LL __int64 const __int64 mod=1000000007; struct matrix { LL mat[2][2]; }; matrix multiply(matrix a,matrix b) { matrix c; memset(c.mat,0,sizeof(c.mat)); for(int i=0;i<2;i++) { for(int j=0;j<2;j++) { if(a.mat[i][j]==0)continue; for(int k=0;k<2;k++) { if(b.mat[j][k]==0)continue; c.mat[i][k]=(c.mat[i][k]+a.mat[i][j]*b.mat[j][k])%(mod-1);//加法不能简写成..+=...%.. } } } return c; } matrix matrixquicklymod(matrix x,LL m) { matrix res; // memset(res.mat,0,sizeof(res.mat)); for(int i=0;i<2;i++) for(int j=0;j<2;j++) res.mat[i][j]=(i==j); while(m) { if(m&1) res=multiply(res,x); m>>=1; x=multiply(x,x); } return res; } LL qmod(LL x, LL y) { LL z=1; while(y) { if(y&1) z=(z*x)%mod; y>>=1; x=(x*x)%mod; } return z; } int main() { LL a,b,n,ma,mb; while(scanf("%I64d%I64d%I64d",&a,&b,&n)!=EOF) { matrix ans; ma=mb=1;//幂 ans.mat[0][0]=1; ans.mat[0][1]=1; ans.mat[1][0]=1; ans.mat[1][1]=0; if(n==0) printf("%I64d ",a%mod); else if(n==1) printf("%I64d ",b%mod); else if(n==2) printf("%I64d ",((a%mod)*(b%mod))%mod); else { ans=matrixquicklymod(ans,n-2); mb=ans.mat[0][0]+ans.mat[1][0]; ma=ans.mat[0][1]+ans.mat[1][1]; ma=ma%(mod-1); mb=mb%(mod-1); a=qmod(a,ma); b=qmod(b,mb); printf("%I64d ",((a%mod)*(b%mod))%mod); } } return 0; }