矩阵快速幂
题目poj3070 http://poj.org/problem?id=3070
题意很简单,就是斐波那契数列的求解,只不过输出的 f【n】(f【n】取模10000) 中的n足够大,暴力一定超时。
题解:
既然暴力会超时,那这里采用矩阵快速幂。
对于斐波那契数列
f【0】=0 f【1】=1
当n大于等于2时,满足f【n】=f【n-1】+f【n-2】;
然后对于矩阵A*B=C
其中矩阵C【i】【j】 是矩阵A【i】【】 * B【】【j】得到的 (矩阵A的 i 行* 矩阵B的 j 列)
f【3】=f【2】+f【1】
是否可以写成
进而
然后递推得到
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<queue> #include<stack> #include<algorithm> #define Max(a,b) ((a)>(b)?(a):(b)) #define Min(a,b) ((a)<(b)?(a):(b)) #define Mem0(x) memset(x,0,sizeof(x)) #define Mem1(x) memset(x,-1,sizeof(x)) #define MemX(x) memset(x,0x3f,sizeof(x)) using namespace std; typedef long long ll; const int inf=0x3f3f3f; const double pi=acos(-1.0); const int mod=10000; struct Mul{ int mt[3][3]; }mat; int f[10]; void init() { mat.mt[1][1]=mat.mt[1][2]=mat.mt[2][1]=1; mat.mt[2][2]=0; f[0]=0; f[1]=f[2]=1; } Mul mul(Mul node1,Mul node2) { Mul ans; ans.mt[1][1]=ans.mt[1][2]=ans.mt[2][1]=ans.mt[2][2]=0; for (int i=1;i<=2;i++){ for (int j=1;j<=2;j++){ for (int k=1;k<=2;k++){ ans.mt[i][j]=ans.mt[i][j]+node1.mt[i][k]*node2.mt[k][j]%mod; } } } /* system("pause"); for (int i=1;i<=2;i++){ for (int j=1;j<=2;j++){ cout<<ans.mt[i][j]<<" "; } cout<<endl; }*/ return ans; } int quick_Mul(ll n) { Mul tmp; tmp.mt[1][1]=tmp.mt[2][2]=1; //初始化单位矩阵 tmp.mt[1][2]=tmp.mt[2][1]=0; while (n){ if (n&1){ tmp=mul(tmp,mat); } n>>=1; mat=mul(mat,mat); } return (tmp.mt[1][1]*f[1]+tmp.mt[1][2]*f[0])%mod; } int main() { ll n; while (scanf("%lld",&n)&&(n!=-1)){ init(); if (n) cout<<quick_Mul(n-1)<<endl; else cout<<n<<endl; } return 0; }