HDU 4291 A Short problem

题意: 求 g(g(g(n))) mod 109+ 7  ,其中g(n)=3*g(n-1)+g(n-2),  g(0)=0,g(1)=1;

分析: 当n 的3的时候内部就超精度了,需要本地暴力找出每层的循环节,最外面的对1000000007取模,找最外层循环节222222224, 在对222222224取模,

         找到次一层循环节183120,这样就可以通过三次快速幂求出结果了

         g(g(g(n)))%1000000007 = g(g(g(n)%183120)%222222224)%1000000007

#include<stdio.h>
#include<string.h>
void mul(__int64 a[][3],__int64 b[][3],__int64 mod)
{
    __int64 c[3][3];
    int i,j,k;
    for(i=1;i<=2;i++)
        for(j=1;j<=2;j++)
        {
            c[i][j]=0;
            for(k=1;k<=2;k++)
                c[i][j]+=((a[i][k]%mod)*(b[k][j]%mod))%mod;
        }
    for(i=1;i<=2;i++)
        for(j=1;j<=2;j++)
            b[i][j]=c[i][j]%mod;
}
__int64 cal(__int64 n,__int64 mod)
{
        if(n==0)
            return 0;
        __int64 a[3][3],b[3][3];
        a[1][1]=3; 
        a[1][2]=1;
        a[2][1]=1; 
        a[2][2]=0;
        b[1][1]=1;
        b[1][2]=b[2][1]=b[2][2]=0;
        n-=1;
        while(n)
        {
            if(n&1)
                mul(a,b,mod);
            mul(a,a,mod);
            n/=2;
        }
        return b[1][1];
}
int main()
{
    __int64 n;
    int i;
    while(scanf("%I64d",&n)!=EOF)
    {
        __int64 t1=cal(n,183120);
        __int64 t2=cal(t1,222222224);
        __int64 t3=cal(t2,1000000007);
        printf("%I64d\n",t3);
    }
    return 0;
}

 

posted @ 2012-09-17 00:21  'wind  阅读(295)  评论(0编辑  收藏  举报