题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1588
题目大意:先要知道一组斐波那契数列
i | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
f(i) | 0 | 1 | 1 | 2 | 3 | 5 | 8 | 13 |
现在知道一组公式g(i)=k*i+b;(i=0,1,2,3...n-1)
让你求出 f(g(i)) 的总和(i=01,2,3,...,n-1),比如给出的数据是2 1 4 100
2*0+1=1 f(1)=1
2*1+1=3 f(3)=2
2*2+1=5 f(5)=5
2*3+1=7 f(7)=13
故sum=21%100
没有什么思路做这个题目。
后来看了题解发现数列的乘法可以构造出矩阵相乘。
fibonacci数列满足 |F(n+1) F(n) |= |1 1|^n
|F(n) F(n-1)| |1 0|
#include<stdio.h> #include<string.h> #define N 2 struct Matrix { __int64 a[N][N]; }res,tmp,ans,B,C,S,AB,AK; Matrix A={1,1,1,0}; //初始化矩阵A Matrix S0={1,0,0,1}; //(A^k)^0 int m; Matrix mul(Matrix x,Matrix y) //矩阵乘法 { memset(tmp.a,0,sizeof(tmp.a)); int i,j,k; for(i=0;i<2;i++) for(j=0;j<2;j++) for(k=0;k<2;k++) { tmp.a[i][j]+=(x.a[i][k]*y.a[k][j]); tmp.a[i][j]%=m; } return tmp; } Matrix quickpow(Matrix origin,int k) //矩阵快速幂 { int i; memset(res.a,0,sizeof(res.a)); for(i=0;i<2;i++) res.a[i][i]=1; while(k) { if(k&1) res=mul(res,origin); origin=mul(origin,origin); k>>=1; } return res; } Matrix add(Matrix x,Matrix y) //矩阵加法 { int i,j; for(i=0;i<2;i++) for(j=0;j<2;j++) tmp.a[i][j]=(x.a[i][j]+y.a[i][j])%m; return tmp; } Matrix bin(int n) //二分 { if(n<=1) return AK; else if(n%2) { B=bin(n-1); C=quickpow(AK,n); return add(B,C); } else { B=bin(n/2); C=quickpow(AK,n/2); C=mul(B,C); return add(B,C); } } void print(Matrix x) { int i,j; for(i=0;i<2;i++) { for(j=0;j<2;j++) printf("%d ",x.a[i][j]); printf("\n"); } } int main() { int k,b,n; while(scanf("%d%d%d%d",&k,&b,&n,&m)!=EOF) { //fibonacci数列满足 |F(n+1) F(n) |= |1 1|^n // |F(n) F(n-1)| |1 0| AB=quickpow(A,b); //A^b // print(AB); AK=quickpow(A,k); //A^k // print(AK); S=bin(n-1); //F(n-1) S=add(S0,S); // print(S); ans=mul(AB,S); printf("%d\n",ans.a[0][1]); } return 0; }
矩阵十题【三】 HDU 1588 Gauss Fibonacci,布布扣,bubuko.com
矩阵十题【三】 HDU 1588 Gauss Fibonacci
原文地址:http://blog.csdn.net/u010468553/article/details/38424973