【矩阵快速幂 && 循环节】HDU

来源:互联网 发布:ansys软件 编辑:程序博客网 时间:2024/05/18 03:06

Problem Description

Given n (1 <= n <= 10^18), You should solve for
g(g(g(n))) mod 10^9 + 7
where
g(n) = 3g(n - 1) + g(n - 2)

g(1) = 1

g(0) = 0

思路:

参考博客:http://blog.csdn.net/a601025382s/article/details/10133651 因为n很大,需要矩阵快速幂。但是要求g(g(n))要求,不能取mod的g(n),所以g(n)特别大。所以得找循环节

#include<cstdio>#include<cstring>using namespace std;struct node{    long long a[3][3];};node c, ans;int Mod[3];//循环节,参考上面链接博客void init()//初始化{    c.a[0][0] = 3;    c.a[0][1] = 1;    c.a[1][0] = 1;    c.a[1][1] = 0;    ans.a[0][0] = 1;    ans.a[1][0] = 0;}node mul(node x, node y, int mod)//矩阵相乘{    node sum;    int i, j, k;    for(i = 0; i < 2; i++)    {        for(j = 0; j < 2; j++)        {            sum.a[i][j] = 0;            for(k = 0; k < 2; k++)            {                sum.a[i][j] += (x.a[i][k] * y.a[k][j])%mod;                sum.a[i][j] %= mod;            }        }    }    return sum;}node sm(node t, long long m, int mod)//矩阵快速幂{    node sum;    memset(sum.a, 0, sizeof(sum.a));    for(int i = 0; i <= 2; i++) sum.a[i][i] = 1;    while(m)    {        if(m & 1) sum = mul(sum, t, mod);        t = mul(t, t, mod);        m = m>>1;    }    return sum;}int main(){    long long n;    while(~scanf("%lld", &n))    {        init();        Mod[0]=183120;        Mod[1]=222222224;        Mod[2]=1000000007;        node temp;        temp.a[0][0] = n;        for(int l = 0; l < 3; l++) {            if(temp.a[0][0] == 0 || temp.a[0][0] == 1)            {                break;            }            temp = sm(c, temp.a[0][0] - 1, Mod[l]);            temp = mul(temp, ans, Mod[l]);        }        printf("%lld\n", temp.a[0][0]);    }}
原创粉丝点击