Codevs1732 Fibonacci数列2

来源:互联网 发布:coc狂暴法术数据 编辑:程序博客网 时间:2024/06/01 18:42

题目

题目描述 Description
在“1250 Fibonacci数列”中,我们求出了第n个Fibonacci数列的值。但是1250中,n<=109。现在,你的任务仍然是求出第n个Fibonacci数列的值,但是注意:n为整数,且1 <= n <= 100000000000000

输入描述 Input Description
输入有多组数据,每组数据占一行,为一个整数n(1 <= n <= 100000000000000)

输出描述 Output Description
输出若干行。每行输出第(对应的输入的)n个Fibonacci数(考虑到数会很大,mod 1000000007)

样例输入 Sample Input
3
4
5

样例输出 Sample Output
2
3
5

数据范围及提示 Data Size & Hint
1 <= n <= 100000000000000

代码

#include<cstdio>#include<cstring>#include<iostream>using namespace std;struct M{    long long mat[5][5];    void INIT(){        memset(mat,0,sizeof(mat));    }    M operator * (M B) const{        M C;        for(int i = 1;i <= 2;i++){            for(int j = 1;j <= 2;j++){                C.mat[i][j] = 0;                for(int k = 1;k <= 2;k++)                    C.mat[i][j] = (C.mat[i][j]+(mat[i][k]*B.mat[k][j]))%1000000007;            }        }        return C;    }};M ksm(M A,long long n){    M B = A;    while(n){        if(n&1)            B = B * A;        A = A*A;        n >>= 1;    }    return B;}int main(){    long long q;    while(cin >> q)    {        if(q == 1 || q == 2){            cout << 1 << endl;            continue;        }//      scanf("%d",&q);        M A;        A.mat[1][1] = A.mat[1][2] = A.mat[2][1] = 1;        A.mat[2][2] = 0;        A = ksm(A,q-2);        printf("%lld\n",A.mat[1][1]%1000000007);    }    return 0;}

评价

分析
仍然是“矩阵优化递推式”。其实就刚才那道Codevs1250 Fibonacci的代码修改一下就能用了。值得注意的是,这道题没有给出数据组数,这个时候来句while(cin >> q)真是极方便的。

理论基础
矩阵乘法+快速幂

原创粉丝点击