Codevs1732 Fibonacci数列2

题目

题目描述 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
#include
#include
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)真是极方便的。

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

你可能感兴趣的:(OI-数论)