【HDOJ 4686】 Arc of Dream (矩阵快速幂)

【HDOJ 4686】 Arc of Dream (矩阵快速幂)

两个公式

a(i) = a(i-1)*Ax+Ay 

b(i) = b(i-1)*Bx+By

0~(n-1) 的a(i)*b(i)

初始矩阵为                                       求幂矩阵为

a0                                                      Ax          0           0          0         Ay 

b0                                                      0            Bx         0          0         By

a0*b0                                             Ax*By     Ay*Bx    Ax*Bx      0      Ay*By

0                                                        0             0           1          1          0

1                                                        0             0           0          0          0

(艾玛 这么生敲矩阵太累人了。。。。还好行列不多。。。

这样经过一次矩阵乘法之后 会变成。。。

a1

b1

a1*b1

a0*b0

1

两次

a2

b2

a2*b2

a0*b0+a1*b1

1

......自己写写看 乘的过程就不写了。。忒累了


然后写个矩阵乘法套个快速幂就WA了………………精度要求 一开始是开成long long了。。。不过初始矩阵传成了int。。。该打。。。。


代码如下:


#include <iostream>
#include <cstdio>
#include <cstring>
#define ll long long
#define mod 1000000007

using namespace std;

typedef struct Matrix Matrix;

struct Matrix
{
    ll mx[5][5];
    void Init(ll ax,ll ay,ll bx,ll by)//初始矩阵
    {
        memset(mx,0,sizeof(mx));
        mx[0][0] = ax;
        mx[0][4] = ay;
        mx[1][1] = bx;
        mx[1][4] = by;
        mx[2][0] = ax*by%mod;
        mx[2][1] = ay*bx%mod;
        mx[2][2] = ax*bx%mod;
        mx[2][4] = ay*by%mod;
        mx[3][2] = mx[3][3] = mx[4][4] = 1;
    }

    void Emp()//单位矩阵
    {
        memset(mx,0,sizeof(mx));
        for(int i = 0; i < 5; ++i) mx[i][i] = 1;
    }

    Matrix operator * (const Matrix a)const//矩阵乘法
    {
        Matrix x;
        memset(x.mx,0,sizeof(x.mx));
        for(int i = 0; i < 5; ++i)
            for(int j = 0; j < 5; ++j)
                for(int k = 0; k < 5; ++k)
                    x.mx[i][j] = (x.mx[i][j]+mx[i][k]*a.mx[k][j]%mod)%mod;
        return x;
    }

};

Matrix pow(Matrix a,ll b)//快速幂
{
    Matrix ans;
    ans.Emp();
    while(b)
    {
        if(b&1) ans = ans*a;
        a = a*a;
        b >>= 1;
    }
    return ans;
}



int main()
{
    ll n,a,b,ax,ay,bx,by;
    while(~scanf("%lld%lld%lld%lld%lld%lld%lld",&n,&a,&ax,&ay,&b,&bx,&by))//没改 杭电的题 注意改成I64d
    {
        a%=mod;
        b%=mod;
        ax%=mod;
        ay%=mod;
        bx%=mod;
        by%=mod;
        Matrix mx;
        mx.Init(ax,ay,bx,by);
        mx = pow(mx,n);
        printf("%lld\n",(((a*mx.mx[3][0]%mod+b*mx.mx[3][1]%mod)%mod+a%mod*b%mod*mx.mx[3][2]%mod)%mod+mx.mx[3][4])%mod);
    }
    return 0;
}


你可能感兴趣的:(矩阵快速幂)