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

来源:互联网 发布:c 用什么软件编程 编辑:程序博客网 时间:2024/05/22 11:38

【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 1000000007using 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;}


0 0
原创粉丝点击