andre_joy

导航

hdu 4291

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

题意:g(n) = 3*g(n-1)+g(n-2),求g(g(g(n)))。

mark:本地打表找循环节。。。囧,第一次做这种题。找到后直接快速幂。

代码:

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <map>
#define LL long long

using namespace std;

const LL P1 = 1000000007;
const LL P2 = 222222224;
const LL P3 = 183120;
LL n,m;

LL solve(LL a, LL b)
{
    if(a < 0) return 0;
    LL tab1[2][2][2] = {3, 1, 1, 0}, tab2[2][2][2] = {1, 0, 0, 1};
    int i, p;
    i = 0;
    p = 1;
    while(a)
    {
        if(a & 1)
        {
            for(int j = 0; j < 2; j++)
                for(int k = 0; k < 2; k++)
                    tab2[p][j][k] = (tab2[!p][j][0]*tab1[i][0][k]+tab2[!p][j][1]*tab1[i][1][k])%b;
            p = 1-p;
        }
        i = 1-i;
        for(int j = 0; j < 2; j++)
            for(int k = 0; k < 2; k++)
                tab1[i][j][k] = (tab1[!i][j][0]*tab1[!i][0][k]+tab1[!i][j][1]*tab1[!i][1][k])%b;
        a >>= 1;
    }
    return tab2[!p][0][0];
}

int main()
{
    while(~scanf("%I64d", &n))
    {
        m = solve(n-1, P3);
        n = solve(m-1, P2);
        m = solve(n-1, P1);
        printf("%I64d\n", m);
    }
    return 0;
}

posted on 2012-09-16 22:03  andre_joy  阅读(263)  评论(0编辑  收藏  举报