POJ3070 斐波那契数列 矩阵快速幂

时间:2019-03-19
本文章向大家介绍POJ3070 斐波那契数列 矩阵快速幂,主要包括POJ3070 斐波那契数列 矩阵快速幂使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

题目链接:http://poj.org/problem?id=3070

题意就是让你求斐波那契数列,不过n非常大,只能用logn的矩阵快速幂来做了

刚学完矩阵快速幂刷的水题,POJ不能用万能头文件是真的烦

#include<iostream>
#include<string.h>
#include<cmath>
#include<cstdio>
using namespace std;
typedef long long ll;
const int inf=1<<30;
const int maxn=1e5+7;
const double pi=acos(-1);
const int mod=10000;
struct matrix{
    ll a[11][11]; //begin with 1
    int r,c;
    matrix(int n,int m):r(n),c(m){memset(a,0,sizeof(a));}
    ll* operator[](int x){return a[x];}
    friend matrix operator*(matrix A,matrix B)
    {
        matrix C(A.r,B.c);
        for(int i=1;i<=A.r;i++)
            for(int j=1;j<=B.c;j++)
                for(int k=1;k<=A.c;k++){
                    C[i][j]+=(A[i][k]*B[k][j])%mod;
                    C[i][j]+=mod;
                    C[i][j]%=mod;
                }
        return C;
    }
};

matrix qpow(matrix A,ll m)//方阵A的m次幂
{
    matrix ans(A.r,A.c);
    for(int i=1;i<=A.r;i++) ans.a[i][i]=1; //单位矩阵
    while(m)
    {
        if(m&1)ans=ans*A;
        A=A*A;
        m>>=1;
    }
    return ans;
}
/*inline void read(ll &x){
    char ch=x=0;
    while(!isdigit(ch))
        ch=getchar();
    while(isdigit(ch))
        x=x*10+ch-'0',ch=getchar();
}*/
int main(){
    ll n;
    while(~scanf("%lld",&n)){
        if(n==-1)break;
        if(n==0){
            cout<<0<<endl;continue;
        }
        matrix a(2,2);        
        a[1][1]=1,a[1][2]=1,a[2][1]=1,a[2][2]=0;
        matrix x1(2,1);
        x1[1][1]=1,x1[2][1]=0;
        matrix ans=qpow(a,n-1)*x1;//0cout<<233<<endl;
        printf("%d\n",ans[1][1]%10000);
    }
    return 0;
}