POJ 3070 Fibonacci.(矩阵快速幂)
来源:互联网 发布:金科信软件 编辑:程序博客网 时间:2024/06/05 03:02
解题思路:用公式递推显然是会超时的,于是根据题目明显的提示,就想到用矩阵快速幂。
之所以快,是运用了二分的思想,算出了矩阵A的值,那么我可以一步算出A*A的值,进而一步算出A*A*A*A的值,进而……
题目链接:点击打开链接
方法一:
#include<cstdio>#include<algorithm>#define N 100000#define MOD 10000using namespace std;int f[N];int Get(int n) //将n转化成二进制并存到数组f{ int cnt=0; while(n) { if(n%2) f[cnt++]=1; else f[cnt++]=0; n/=2; } return cnt;}int b[2][2],s[2][2]; //数组b保存矩阵A,A*A,A*A*A*A……数组s保存答案。void Cal(int k){ int t[2][2]; for(int i=0;i<2;i++) for(int j=0;j<2;j++) t[i][j]=s[i][j]; if(k) //此二进制位为1. { s[0][0]=((t[0][0]*b[0][0])%MOD+(t[0][1]*b[1][0])%MOD)%MOD; //矩阵乘法 s[0][1]=((t[0][0]*b[0][1])%MOD+(t[0][1]*b[1][1])%MOD)%MOD; s[1][0]=((t[1][0]*b[0][0])%MOD+(t[1][1]*b[1][0])%MOD)%MOD; s[1][1]=((t[1][0]*b[0][1])%MOD+(t[1][1]*b[1][1])%MOD)%MOD; } for(int i=0;i<2;i++) for(int j=0;j<2;j++) t[i][j]=b[i][j]; //继续求下一个A*A*A*A*A*A*A*A…… b[0][0]=((t[0][0]*t[0][0])%MOD+(t[0][1]*t[1][0])%MOD)%MOD; b[0][1]=((t[0][0]*t[0][1])%MOD+(t[0][1]*t[1][1])%MOD)%MOD; b[1][0]=((t[1][0]*t[0][0])%MOD+(t[1][1]*t[1][0])%MOD)%MOD; b[1][1]=((t[1][0]*t[0][1])%MOD+(t[1][1]*t[1][1])%MOD)%MOD;}int main(){ int n; while(scanf("%d",&n)==1) { if(n==-1) break; int len=Get(n); b[0][0]=1; b[0][1]=1; b[1][0]=1; b[1][1]=0; //初始化。 s[0][0]=1; s[0][1]=0; s[1][0]=0; s[1][1]=1; for(int i=0;i<len;i++) Cal(f[i]); printf("%d\n",s[0][1]); } return 0;}
方法二:
更棒的解法来了,既然是二分,那么我们用递归的方法来写;
eg: S(6)=A^6; -> S(6)=S(3)*S(3);->S(3)=A*S(1)*S(1);S(1)=A; return;
#include<cstdio>#include<cstring>#include<algorithm>#define MOD 10000using namespace std;struct Matrix{ int f[5][5];};int m=2; //矩阵为2*2Matrix Mul(Matrix U,Matrix V) //矩阵相乘{ Matrix S; memset(S.f,0,sizeof(S.f)); for(int k=0;k<m;k++) for(int i=0;i<m;i++) for(int j=0;j<m;j++) S.f[k][i]=(U.f[k][j]*V.f[j][i]+S.f[k][i])%MOD; return S;}Matrix Pow(Matrix S,int k) //求解 A^k{ if(k==0) { memset(S.f,0,sizeof(S.f)); for(int i=0;i<m;i++) S.f[i][i]=1; return S; } if(k==1) return S; Matrix X=Pow(S,k/2); if(k%2) return Mul(Mul(X,X),S); else return Mul(X,X);}int main(){ int n; while(scanf("%d",&n)==1) { if(n==-1) break; Matrix A; A.f[0][0]=1; A.f[0][1]=1; A.f[1][0]=1; A.f[1][1]=0; Matrix S=Pow(A,n); printf("%d\n",S.f[0][1]); } return 0;}
0 0
- POJ 3070 Fibonacci 矩阵快速幂
- poj - 3070 - Fibonacci(矩阵快速幂)
- 矩阵快速幂 Fibonacci 3070 poj
- POJ 3070 Fibonacci (矩阵快速幂)
- poj 3070 Fibonacci (矩阵快速幂)
- poj 3070 Fibonacci(矩阵快速幂)
- poj 3070 Fibonacci 矩阵快速幂
- POJ 3070 Fibonacci(矩阵快速幂)
- poj 3070 Fibonacci(矩阵快速幂)
- POJ-3070 Fibonacci 矩阵快速幂
- Fibonacci - POJ 3070 矩阵乘法快速幂
- poj 3070 Fibonacci(矩阵快速幂)
- poj 3070 Fibonacci 矩阵快速幂
- POJ 3070 Fibonacci(矩阵快速幂)
- POJ 3070 Fibonacci(矩阵快速幂)
- poj 3070 Fibonacci 矩阵快速幂
- poj 3070 Fibonacci 【矩阵快速幂】
- POJ 3070 Fibonacci.(矩阵快速幂)
- 取给定正整数的指定bit位开始的指定长度的数据
- C++~数组/指针
- win32消息
- 6.1 理解事务
- 小马哥----高仿htc_m8tl手机刷机 芯片为6582 外观与行货一致,操作与检测基本无差别
- POJ 3070 Fibonacci.(矩阵快速幂)
- fcntl函数
- 自己写的一个C#日志管理类
- 哈哈
- online_judge_1077
- 参数化模块
- background-position 用法详细介绍
- ios越狱手机上root权限获取
- 黑马程序员_java编程思想——递归