HDU -4686 (矩阵快速幂)

题目链接: Arc of Dream

题意

给你f[n]和g[n]的递推关系,和你说明了一些原始量的大小,让你推Arc[n].

题意

最近好长时间一直在WA,本想放弃一段时间,奈何功夫不负有心人,终于找出了诸多漏洞所在。 本题的大数会爆Long long , 需要不断取余。主要的错误还是在于我的代码的细节问题,赋值字母竟然输错了。而且还有个重大发现,以前发现数组开小了会TLE,没想到这次开大了还是会TLE,看来TLE的原因好复杂。比赛的时候推不出来转移矩阵。没想到还需要多化几步才行。
在这里插入图片描述
{ 1 A X ∗ B X A X ∗ B Y A Y ∗ B X A Y ∗ B Y 0 A X ∗ B X A X ∗ B Y A Y ∗ B X A Y ∗ B Y 0 0 A X 0 A Y 0 0 0 B X B Y 0 0 0 0 1 } × { S n − 1 A [ n − 2 ] ∗ B [ n − 2 ] A [ n − 2 ] B [ n − 2 ] 1 } = { S n A [ n − 1 ] ∗ B [ n − 1 ] A [ n − 1 ] B [ n − 1 ] 1 } \left\{ \begin{matrix} 1&AX*BX&AX*BY&AY*BX&AY*BY\\ 0&AX*BX&AX*BY&AY*BX&AY*BY\\ 0&0&AX&0&AY\\ 0&0&0&BX&BY\\ 0&0&0&0&1 \end{matrix} \right\}\times \left\{ \begin{matrix} S_{n - 1}\\ A[n - 2]*B[n - 2]\\ A[n - 2]\\ B[n - 2]\\ 1 \end{matrix} \right\}= \left\{ \begin{matrix} S_n\\ A[n - 1] * B[n - 1]\\ A[n - 1]\\ B[n - 1]\\ 1 \end{matrix} \right\} 10000AXBXAXBX000AXBYAXBYAX00AYBXAYBX0BX0AYBYAYBYAYBY1×Sn1A[n2]B[n2]A[n2]B[n2]1=SnA[n1]B[n1]A[n1]B[n1]1

#include <bits/stdc++.h>
using namespace std;
typedef  long long ll;
struct Matrix{
    ll m[7][7];
};
const ll mod = 1000000007;
Matrix mul(Matrix A,Matrix B)
{
    Matrix tmp;
    memset(tmp.m,0,sizeof(tmp.m));
    for(int i = 1; i <= 5 ;i++)
    for(int j = 1; j <= 5 ;j++)
        for(int k = 1; k <= 5 ;k++)
    {
        tmp.m[i][j] = (tmp.m[i][j] + A.m[i][k] * B.m[k][j]) % mod;
    }
    return tmp;
}
Matrix pow(Matrix A,ll n)
{
    int i;
    Matrix res;
    memset(res.m,0,sizeof(res.m));
    for(i = 1; i <= 5 ;i++)
        res.m[i][i] = 1;
    while(n)
    {
        if(n & 1)
            res = mul(res,A);
        A = mul(A,A);
        n >>= 1;
    }
    return res;
}
int main()
{
   ll N,A0,B0,AX,AY,BX,BY;
   while(cin >> N )
   {
   cin >> A0 >> AX >> AY >> B0 >> BX >> BY;
   if(!N)
    {
        cout << '0' << endl;
        continue;
    }
   Matrix A,B,C;
   A0 %= mod;
   AX %= mod;
   AY %= mod;
   B0 %= mod;
   BX %= mod;
   BY %= mod;
   memset(A.m,0,sizeof(A.m));
   memset(C.m,0,sizeof(C.m));
   A.m[1][1] = 1;
   A.m[1][2] = A.m[2][2] = AX*BX%mod;
   A.m[1][3] = A.m[2][3] = AX*BY%mod;
   A.m[1][4] = A.m[2][4] = AY*BX%mod;
   A.m[1][5] = A.m[2][5] = AY*BY%mod;
   A.m[3][3] = AX;
   A.m[3][5] = AY;
   A.m[4][4] = BX;
   A.m[4][5] = BY;
   A.m[5][5] = 1;
   A = pow(A, N - 1);
   C.m[1][1] = A0 * B0 % mod;
   C.m[2][1] = A0 * B0 % mod;
   C.m[3][1] = A0;
   C.m[4][1] = B0;
   C.m[5][1] = 1;
   B = mul(A, C);
   cout << B.m[1][1] << endl;
   }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值