HDU 4291 A Short problem(矩阵快速幂+循环节)

来源:互联网 发布:上海关键词优化 编辑:程序博客网 时间:2024/05/17 21:43

题目链接“:

http://acm.hdu.edu.cn/showproblem.php?pid=4291


题意:

g(0)=0,g(1)=1;

g(n) = 3g(n - 1) + g(n - 2);

求g(g(g(n))) mod 109 + 7


分析:

首先我们得认识到,如果一层一层算是必定会超时的。

其次,取模运算是有循环节的。

step1我们找出g(x)%1000000007的循环节 mod1

step2 设g(g(n)) = g(x) x=g(n) 对mod1 取模得到mod2.

剩下的工作就是进行三次的快速幂运算 从内到外进行。

代码如下:

#include <iostream>#include <cstdio>using namespace std;typedef long long LL;const LL mod = 1e9+7;const LL mod1 = 222222224;const LL mod2 = 183120;//´ò±íÕÒÑ­»·½Ú//mod 1e9+7 ===> mod1 ,mod mod1 ===>mod2;/*int main(){    LL f0=0,f1=1;    for(LL i=1;;i++){        LL tmp = (3 * f1 + f0)%mod;        f0 = f1 ;        f1 = tmp;        if(f0==0&&f1==1){            printf("ans: %d\n",i);            break;        }    }    return 0;}*/struct matrix{    LL a[2][2];};matrix I={    1,0,    0,1};matrix multi(matrix A,matrix B,int mod){    matrix C;    for(int i=0;i<2;i++){        for(int j = 0; j < 2;j++){            C.a[i][j]=0;            for(int k=0;k<2;k++)                C.a[i][j]=(C.a[i][j]+A.a[i][k]*B.a[k][j])%mod;        }    }    return C;}LL pow(matrix A ,LL n,LL mod){    matrix tmp = I;    while(n){        if(n&1)            tmp= multi(tmp,A,mod);        n>>=1;        A=multi(A,A,mod);    }    return tmp.a[0][0];}int main(){    LL n;    while(~scanf("%lld",&n)){        matrix A= {            3,1,            1,0        };        if(n>=2) n = pow(A,n-1,mod2);        if(n>=2) n = pow(A,n-1,mod1);        if(n>=2) n = pow(A,n-1,mod);        printf("%I64d\n",n);    }    return 0;}



0 0