hdu 2855 Fibonacci Check-up

点击打开hdu 2855

思路: 递推+矩阵快速幂

分析:

1 题目的意思是给定n和m,要求

  

2 这一题有两种思路,对于这种的题肯定是有递推式的,那么找不到递推式的时候我们尝试去打表

   下面我打出了前几十项,发现了n >= 2的时候有f(n) = 3*f(n-1)-f(n-2),那么我们可以利用矩阵快速幂求f(n)

  

3 另一种思路是考虑f(n) = f(n-1) + f(n-2),那么我们可以利用矩阵求出任意的f(n)

   1 1 *  f(n-1) = f(n)

   1 0    f(n-2)    f(n-1)

   那么对于n >= 2的时候,我们假设左边的矩阵为A,那么A^(n-1)即可求出答案

   那么A^(n-1)为 f(n) f(n-1)

                          f(n-1) f(n-2)

   那么根据我们知道二项式定理为(a+b)^n=C(n,0)a^n+C(n,1)a^(n-1)*b+C(n,2)a^(n-2)*b^2+...+C(n,n)b^n

   那么我们发现所求的式子和上面很像,因为f(n)可以利用上面的A矩阵的n-1次方求出

   那么原式所求变成(1+A)^n,这里的1为单位矩阵。因为做了n次方,那么最终的答案就是ans.mat[0][1] 或ans.mat[1][0]

代码:

// 方法一
/************************************************
 * By: chenguolin                               *
 * Date: 2013-08-30                             *
 * Address: http://blog.csdn.net/chenguolinblog *
 ************************************************/
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

const int N = 2;

int n , MOD;
struct Matrix{
    int mat[N][N];
    Matrix operator*(const Matrix &m)const{
        Matrix tmp;
        for(int i = 0 ; i < N ; i++){
            for(int j = 0 ; j < N ; j++){
                tmp.mat[i][j] = 0;
                for(int k = 0 ; k < N ; k++)
                    tmp.mat[i][j] += mat[i][k]*m.mat[k][j]%MOD;
                tmp.mat[i][j] %= MOD;
            }
        }
        return tmp;
    }
};

int Pow(Matrix m){
    if(n <= 1) return n%MOD;
    Matrix ans;
    ans.mat[0][0] = ans.mat[1][1] = 1;
    ans.mat[0][1] = ans.mat[1][0] = 0;
    n--;
    while(n){
        if(n&1)
            ans = ans*m;
        n >>= 1;
        m = m*m;
    }
    return (ans.mat[0][0]%MOD+MOD)%MOD;
}

int main(){
    Matrix m;
    m.mat[0][0] = 3 ; m.mat[0][1] = -1;
    m.mat[1][0] = 1 ; m.mat[1][1] = 0;
    int cas;
    scanf("%d" , &cas);
    while(cas--){
         scanf("%d%d" , &n , &MOD);
         printf("%d\n" , Pow(m));
    }
    return 0;
}
/************************************************
 * By: chenguolin                               *
 * Date: 2013-08-30                             *
 * Address: http://blog.csdn.net/chenguolinblog *
 ************************************************/
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

const int N = 2;

int n , MOD;
struct Matrix{
    int mat[N][N];
    Matrix operator*(const Matrix &m)const{
        Matrix tmp;
        for(int i = 0 ; i < N ; i++){
            for(int j = 0 ; j < N ; j++){
                tmp.mat[i][j] = 0;
                for(int k = 0 ; k < N ; k++)
                    tmp.mat[i][j] += mat[i][k]*m.mat[k][j]%MOD;
                tmp.mat[i][j] %= MOD;
            }
        }
        return tmp;
    }
};

int Pow(Matrix m){
    if(n <= 1) return n%MOD;
    Matrix ans;
    ans.mat[0][0] = ans.mat[1][1] = 1;
    ans.mat[0][1] = ans.mat[1][0] = 0;
    while(n){
        if(n&1)
            ans = ans*m;
        n >>= 1;
        m = m*m;
    }
    return ans.mat[1][0]%MOD;
}

int main(){
    Matrix m;
    m.mat[0][0] = 2 ; m.mat[0][1] = 1;
    m.mat[1][0] = 1 ; m.mat[1][1] = 1;
    int cas;
    scanf("%d" , &cas);
    while(cas--){
        scanf("%d%d" , &n , &MOD);
        printf("%d\n" , Pow(m));
    }
    return 0;
}
时间: 2024-08-03 06:55:13

hdu 2855 Fibonacci Check-up的相关文章

hdu 3117 Fibonacci Numbers

点击此处即可传送到hdu 3117 **Fibonacci Numbers** Problem Description The Fibonacci sequence is the sequence of numbers such that every element is equal to the sum of the two previous elements, except for the first two elements f0 and f1 which are respectively

hdu 1568 Fibonacci

点击此处即可传送hdu 1568 **Fibonacci** Problem Description 2007年到来了.经过2006年一年的修炼,数学神童zouyu终于把0到100000000的Fibonacci数列 (f[0]=0,f[1]=1;f[i] = f[i-1]+f[i-2](i>=2))的值全部给背了下来. 接下来,CodeStar决定要考考他,于是每问他一个数字,他就要把答案说出来,不过有的数字太长了.所以规定超过4位的只要说出前4位就可以了,可是CodeStar自己又记不住.于

hdu 1021 Fibonacci Again

点击此处即可传送hdu 1021 Fibonacci Again Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 44439 Accepted Submission(s): 21214 Problem Description There are another kind of Fibonacci numbers: F(0) = 7, F(1)

【HDU 4786 Fibonacci Tree】最小生成树

一个由n个顶点m条边(可能有重边)构成的无向图(可能不连通),每条边的权值不是0就是1. 给出n.m和每条边的权值,问是否存在生成树,其边权值和为fibonacci数集合{1,2,3,5,8...}中的一个. 求最小生成树和最大生成树,得到生成树边权和的下界left和上界right.这道题由于每条边权值不是0就是1,因此生成树边权和可以覆盖到[left,right]的每一个数.那么求得[left,right],看是否有fibonacci数在区间内就可以了. 1 #include <cstdio>

HDOJ(HDU) 1708 Fibonacci String

Problem Description After little Jim learned Fibonacci Number in the class , he was very interest in it. Now he is thinking about a new thing – Fibonacci String . He defines : str[n] = str[n-1] + str[n-2] ( n > 1 ) He is so crazying that if someone g

hdu 1848 Fibonacci again and again

这是尼姆博弈的变型; 还是博弈,但是这次要用Sg函数最后异或等于0后手赢 反之,先手赢 #include <iostream> #include <cstring> #include <cstdio> using namespace std; int f[100]={1,2,3,5}; int e[1005]={0,1,2,3}; int b[16]; void Init() { for(int i=3; f[i-1]<=1000; i++) f[i] = f[i

矩阵快速幂专题【完结】

第一题 hdu 1757 A Simple Math Problem 点击打开链接 思路:矩阵快速幂 分析: 1 最简单的矩阵快速幂的题目,直接利用矩阵求解即可 点击打开查看代码 第二题 hdu 1575 Tr A 点击打开hdu 1575 思路: 矩阵快速幂 分析: 1 题目给定一个n*n的矩阵要求矩阵的k次幂之后的矩阵的对角线的和 2 矩阵快速幂的裸题 点击打开查看代码 第三题 hdu 2604 Queuing 点击打开hdu 2604 思路: 递推+矩阵快速幂 分析; 1 根据题目的意思,

hdu 3306 Another kind of Fibonacci

点击此处即可传送hdu 3306 **Another kind of Fibonacci** Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 2005 Accepted Submission(s): 787 Problem Description As we all known , the Fibonacci series : F(0) =

hdu 1588 Gauss Fibonacci

点击此处即可传送hdu 1588 **Gauss Fibonacci** Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2849 Accepted Submission(s): 1179 Problem Description Without expecting, Angel replied quickly.She says: "I'v h