Codevs1250 Fibonacci数列

来源:互联网 发布:如意时时彩源码 编辑:程序博客网 时间:2024/06/06 08:45

题目

题目描述 Description
定义:f0=f1=1, fn=fn-1+fn-2(n>=2)。{fi}称为Fibonacci数列。

输入n,求fn mod q。其中1<=q<=30000。

输入描述 Input Description
第一行一个数T(1<=T<=10000)。

以下T行,每行两个数,n,q(n<=109, 1<=q<=30000)

输出描述 Output Description
文件包含T行,每行对应一个答案。

样例输入 Sample Input
3

6 2

7 3

7 11

样例输出 Sample Output
1

0

10

数据范围及提示 Data Size & Hint
1<=T<=10000

n<=109, 1<=q<=30000

代码

//By Chorolop#include<cstdio>#include<cstring>#include<iostream>using namespace std;int m;struct M{    int 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]);                C.mat[i][j] %= m;            }        }        return C;    }};M ksm(M A,int n){    M B = A;    while(n){        if(n&1)            B = B * A;        A = A*A;        n >>= 1;    }    return B;}int main(){    int T;    scanf("%d",&T);    while(T--){        int q;        scanf("%d%d",&q,&m);        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("%d\n",(A.mat[1][1]+A.mat[1][2])%m);    }    return 0;}

评价

这道题其实只能算入门题,用于理解“矩阵优化递推式”的。
对于这道题我们有f(n) = f(n-1) + f(n-2),那其实可以看作f(n) = 1 * f(n-1) + 1 * f(n-2),再联系矩阵乘法的过程就能猜想出目标矩阵了,然后运用快速幂算法合并计算需要的矩阵表达式。

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

原创粉丝点击