HDU5950(矩阵快速幂)

转载:自己看方便

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5950

题意:f(n) = f(n-1) + 2*f(n-2) + n^4,f(1) = a , f(2) = b,求f(n)

思路:对矩阵快速幂的了解仅仅停留在fib上,重现赛自己随便乱推还一直算错,快两个小时才a还wa了好几次....

主要就是构造矩阵:(n+1)^4 = n^4 + 4n^3 + 6n^2 + 4n + 1

 

|1   2   1   4   6   4   1|     |   f(n+1)   |           |    f(n+2)    |

|1   0   0   0   0   0   0|     |     f(n)     |           |    f(n+1)    |

|0   0   1   4   6   4   1|     | (n+1)^4  |           |  (n+2)^4   |

|0   0   0   1   3   3   1|  * | (n+1)^3  |     =    |  (n+2)^3   |

|0   0   0   0   1   2   1|     | (n+1)^2  |           |  (n+2)^2  |

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

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



#include<cstdio>
using namespace std;
typedef long long ll;
const ll mod = 2147493647;
ll n,a,b;
struct Matrix
{
    ll m[7][7];
    void init1()
    {
        m[0][0] = b,m[0][1] = 0,m[0][2] = 0,m[0][3] = 0,m[0][4] = 0,m[0][5] = 0,m[0][6] = 0;
        m[1][0] = a,m[1][1] = 0,m[1][2] = 0,m[1][3] = 0,m[1][4] = 0,m[1][5] = 0,m[1][6] = 0;
        m[2][0] = 16,m[2][1] = 0,m[2][2] = 0,m[2][3] = 0,m[2][4] = 0,m[2][5] = 0,m[2][6] = 0;
        m[3][0] = 8,m[3][1] = 0,m[3][2] = 0,m[3][3] = 0,m[3][4] = 0,m[3][5] = 0,m[3][6] = 0;
        m[4][0] = 4,m[4][1] = 0,m[4][2] = 0,m[4][3] = 0,m[4][4] = 0,m[4][5] = 0,m[4][6] = 0;
        m[5][0] = 2,m[5][1] = 0,m[5][2] = 0,m[5][3] = 0,m[5][4] = 0,m[5][5] = 0,m[5][6] = 0;
        m[6][0] = 1,m[6][1] = 0,m[6][2] = 0,m[6][3] = 0,m[6][4] = 0,m[6][5] = 0,m[6][6] = 0;
    }
    void init2()
    {
        m[0][0] = 1,m[0][1] = 2,m[0][2] = 1,m[0][3] = 4,m[0][4] = 6,m[0][5] = 4,m[0][6] = 1;
        m[1][0] = 1,m[1][1] = 0,m[1][2] = 0,m[1][3] = 0,m[1][4] = 0,m[1][5] = 0,m[1][6] = 0;
        m[2][0] = 0,m[2][1] = 0,m[2][2] = 1,m[2][3] = 4,m[2][4] = 6,m[2][5] = 4,m[2][6] = 1;
        m[3][0] = 0,m[3][1] = 0,m[3][2] = 0,m[3][3] = 1,m[3][4] = 3,m[3][5] = 3,m[3][6] = 1;
        m[4][0] = 0,m[4][1] = 0,m[4][2] = 0,m[4][3] = 0,m[4][4] = 1,m[4][5] = 2,m[4][6] = 1;
        m[5][0] = 0,m[5][1] = 0,m[5][2] = 0,m[5][3] = 0,m[5][4] = 0,m[5][5] = 1,m[5][6] = 1;
        m[6][0] = 0,m[6][1] = 0,m[6][2] = 0,m[6][3] = 0,m[6][4] = 0,m[6][5] = 0,m[6][6] = 1;
    }
    Matrix operator * (Matrix t)
    {
        Matrix res;
        for (int i = 0; i < 7; i++)
        {
            for (int j = 0; j < 7; j++)
            {
                res.m[i][j] = 0;
                for (int k = 0;k < 7; k++)
                    res.m[i][j] = (res.m[i][j] + (m[i][k] % mod) * (t.m[k][j] % mod) % mod) % mod;
            }
        }
        return res;
    }
    Matrix operator ^ (int k)
    {
        Matrix res,s;
        res.init2();
        s.init2();
        while(k)
        {
            if(k & 1)
                res = res * s;
            k >>= 1;
            s = s * s;
        }
        return res;
    }
};
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%lld %lld %lld",&n,&a,&b);
        if(n == 1)
        {
            printf("%lld\n",a % mod);
            continue;
        }
        if(n == 2)
        {
            printf("%lld\n",b % mod);
            continue;
        }
        Matrix ans,t;
        ans.init1();
        t.init2();
        ans = (t^(n-3)) * ans;
        printf("%lld\n",ans.m[0][0]);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值