首先理一理快速幂 之前总结过但没记录下来
首先对于 将n看成二进制的形式比如 那么 以此类推 每一位都会判断一遍是否是1 是就乘起来
现在在来讲矩阵快速幂:
首先现代知识矩阵乘法 (直接上代码):
void multi(int a[][MAX],int b[][MAX]){ int temp[3][3]; memset(temp,0,sizeof(temp)); for(int i=0;i<2;i++) for(int j=0;j<2;j++) for(int k=0;k<2;k++) temp[i][j]=(temp[i][j]+(a[i][k]*b[k][j]))%mod; for(int i=0;i<2;i++) for(int j=0;j<2;j++) a[i][j]=temp[i][j]; }
显然矩阵快速幂就是求 矩阵的幂 代码:
void Pow(int a[][MAX],int n){ memset(res,0,sizeof(res)); for(int i=0;i<2;i++) res[i][i]=1; while(n){ if(n&1){ multi(res,a); } multi(a,a); n>>=1; } }
那么我们再来讲应用 :
斐波那契数列 :0, 1, 1, 2, 3, 5, 8, 13, 21, 34, …
f(x)=f(x-1)+f(x-2);
用矩阵表示及: (重点) 有点类似于转移方程;
那么 前一个以此递推 可以得到一个等比数列
接下来就和快速幂一个道理了 然后输出对应n位的值
#include<iostream> #include<stdio.h> #include<string.h> using namespace std; const int MAX=3; const int mod=1e4; void multi(int a[][MAX],int b[][MAX]){ int temp[3][3]; memset(temp,0,sizeof(temp)); for(int i=0;i<2;i++) for(int j=0;j<2;j++) for(int k=0;k<2;k++) temp[i][j]=(temp[i][j]+(a[i][k]*b[k][j]))%mod; for(int i=0;i<2;i++) for(int j=0;j<2;j++) a[i][j]=temp[i][j]; } int res[MAX][MAX]; void Pow(int a[][MAX],int n){ memset(res,0,sizeof(res)); for(int i=0;i<2;i++) res[i][i]=1; while(n){ if(n&1){ multi(res,a); } multi(a,a); n>>=1; } } int main(){ int n; while(scanf("%d",&n)!=EOF&&n!=-1){ int T[MAX][MAX]={{1,1},{1,0}}; Pow(T,n); printf("%d\n",res[0][1]); } }