hdu4686 矩阵快速幂 多校第九场

递推关系求第n项,n很大时明显应该想到矩阵的,比赛时推公式,太挫了

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
using namespace std;
#define ll long long
#define mod 1000000007
#define size 5
ll n,a0,ax,ay,b0,bx,by;
ll temp[size][size];
void init(ll t[][size])
{
    for(int i=0;i<size;++i)
        for(int j=0;j<size;++j)
        t[i][j]=0;
}
void mul(ll a[][size],ll b[][size])
{
    init(temp);
    for(int i=0;i<size;++i)
        for(int j=0;j<size;++j)
    {
        for(int k=0;k<size;++k)
        {
            temp[i][j]+=a[i][k]*b[k][j]%mod;
            //if(temp[i][j]>=mod)
                temp[i][j]%=mod;
        }
        temp[i][j]=(temp[i][j]%mod+mod)%mod;
    }
    for(int i=0;i<size;++i)
        for(int j=0;j<size;++j)
        a[i][j]=temp[i][j];
}
void pow_mod(ll res[][size],ll a[][size],ll b)
{
    init(res);
    if(b<=0) return;
    for(int i=0;i<size;++i) res[i][i]=1;
    while(b)
    {
        if(b&1)
            mul(res,a);
        b>>=1;
        mul(a,a);
    }
}
ll res[size][size],a[size][size];
ll b[size],ans[size];
int main ()
{
    while(cin>>n)
    {
        cin>>a0>>ax>>ay;
        cin>>b0>>bx>>by;
        a0%=mod;ax%=mod;ay%=mod;
        b0%=mod;bx%=mod;by%=mod;
        if(n==0)
        {
            printf("0\n");
            continue;
        }
        init(a);
        a[0][0]=1;a[0][3]=1;
        a[1][1]=ax;a[1][4]=ay;
        a[2][2]=bx;a[2][4]=by;
        a[3][1]=ax*by%mod;a[3][2]=ay*bx%mod;a[3][3]=ax*bx%mod;a[3][4]=ay*by%mod;
        a[4][4]=1;
        pow_mod(res,a,n);
        
        b[0]=0;b[1]=a0;b[2]=b0;b[3]=a0*b0%mod;b[4]=1;

        for(int i=0;i<size;++i)
        {
            ans[i]=0;
            for(int k=0;k<size;++k)
            {
                ans[i]+=res[i][k]*b[k]%mod;
                ans[i]%=mod;
            }
            ans[i]=(ans[i]%mod+mod)%mod;
        }
        cout<<ans[0]<<endl;
    }
    return 0;
}


你可能感兴趣的:(hdu4686 矩阵快速幂 多校第九场)