矩阵快速幂

题目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;
}
原文地址:https://www.cnblogs.com/q1204675546/p/10705630.html