矩阵快速幂 !

来源:互联网 发布:顶点软件牛叉诊股 编辑:程序博客网 时间:2024/05/29 14:31

Description

一般而言,兔子在出生两个月后,就有繁殖能力,一对兔子每个月能生出一对小兔子来。如果所有兔子都不死,那么一年以后可以繁殖多少对兔子?这个问题难不倒农夫John,但当地的农夫Jack要有意为难他。刚开始时,John养了一对小兔子,Jack自第3个月起送John若干对兔子,假定第n个月送 n对兔子。兔子繁殖后形成新的兔子序列:
F= Fn-1 + Fn-2 +n,(n>1)F1=1 F=1
给定一个整数n,求Fn是多少?上述问题,John自然是答不上来,现在请你帮助。

Input

多组数据,每组一行,其上有一个整数n(0<n<=10000000000000)

Output

每组输出一行,输出Fn (mod 100000007) 

Sample Input

5

Sample Output

20

首先构造矩阵。

|f(n)    |                        | 1  1  1  0  |                | f(n-1)  |

|f(n-1) |              =        | 1  0  0  0  |       *        | f(n-2) |

|n+1    |                       | 0  0  1  1  |                 |    n     |

| 1       |                       | 0  0  0  1  |                |     1     |

     ans                                 temp                     begin


ans 矩阵 和 begin 矩阵两个的关系是前后项的关系,即n变成n+1.

其余参考快速幂即可。



#include<iostream>#include<cstdio>#include<string.h>#include<math.h>#include<string>#include<map>#include<set>#include<vector>#include<algorithm>#include<queue>using namespace std;const int mod = 100000007;struct matrix{//构造矩阵,默认元素全为0.    long long m[4][4];       //wa了一次,主要不能用int    matrix(){        memset(m,0,sizeof(m));    }    void ini(){  // 初始化函数,初始化矩阵为单位阵        for(int i=0;i<4;i++){            m[i][i] = 1;        }    }};matrix mutl(matrix a, matrix b)//矩阵乘法{    matrix fin;    memset(fin.m,0,sizeof(fin.m));    for(int i=0;i<4;i++){        for(int j=0;j<4;j++){            for(int k=0;k<4;k++){                fin.m[i][j] += a.m[i][k]*b.m[k][j];            }            fin.m[i][j] %= mod;   //1  模余        }    }    return fin;}matrix mypow(matrix temp,long long n)//快速幂{    matrix ans;    ans.ini();    while(n!=0){        if(n&1) ans = mutl(ans,temp);        temp = mutl(temp,temp);        n >>= 1;    }    return ans;}int main(){    long long  n;    matrix temp;//构造temp矩阵    temp.ini();    temp.m[0][1] = 1;    temp.m[0][2] = 1;    temp.m[1][0] = 1;    temp.m[1][1] = 0;    temp.m[2][3] = 1;    int res[4] = {1,1,3,1};//beg不用构造为矩阵,数组就可以。    while(cin >> n){        if(n>2){            long long suma = 0;            matrix en = mypow(temp,n-2);    //让temp矩阵不断乘。注意是(n-2)次            for(int i=0;i<4;i++){                suma += ( (en.m[0][i]%mod)*(res[i]%mod) )%mod;//2  取余,同余定理            }            suma %= mod;    //3   结果再取余            cout << suma << endl;        }        else cout << 1 <<endl;    }}


0 0
原创粉丝点击