HDU5015 233 Matrix 矩陣乘法

矩陣乘法。

可以觀察出來,每一列往下一列和每一行往下一行遞推都是固定的,\large m<1e9 那麼肯定不能把行當狀態矩陣,而\large n<10,可以把列當成狀態矩陣。一列一列的往前推。對於2333這些的加可以通過,狀態矩陣頭上加上兩個,23和3,即

                                                             \large f[n+2]=[23,3,a_{1,0},a_{2,0},\cdots,a_{n,0}]

來解決。

可以推出轉移矩陣(n=3的時候)

 

                                                                                \large \begin{bmatrix} 10& 0 & 10 & 10 &10 \\ 1& 1 &1 &1 &1 \\ & & 1 & 1 &1 \\ & & & 1 & 1\\ & & & & 1 \end{bmatrix}

#include <bits/stdc++.h>
#define ms(a,b) memset(a,b,sizeof(a))
#define mc(a,b) memcpy(a,b,sizeof(b)) 
using namespace std;
typedef long long ll;
const int N=15;
const ll mod=1e7+7;
int n,m;
void mul1(ll f[N],ll a[N][N])
{
    ll c[N];
    ms(c,0);
    for(int j=1;j<=n+2;j++)
        for(int k=1;k<=n+2;k++) c[j]=(c[j]+f[k]*a[k][j])%mod;
    mc(f,c);
}
void mul2(ll a[N][N],ll b[N][N])
{
    ll c[N][N];
    ms(c,0);
    for(int i=1;i<=n+2;i++)
        for(int j=1;j<=n+2;j++)
            for(int k=1;k<=n+2;k++) c[i][j]=(c[i][j]+a[i][k]*b[k][j])%mod;
    mc(a,c);
}
void qpow(ll a[N][N],int b)
{
    ll c[N][N];
    ms(c,0);
    for(int i=1;i<=n+2;i++) c[i][i]=1;
    while(b)
    {
        if(b&1) mul2(c,a);
        b>>=1;
        mul2(a,a);
    }
    mc(a,c);
}
int main()
{
    ll f[N],a[N][N];
    while(~scanf("%d%d",&n,&m))
    {
        ms(a,0);
        ms(f,0);
        f[1]=23,f[2]=3;
        a[1][1]=10;
        a[2][1]=1;
        a[2][2]=1;
        for(int i=3;i<=n+2;i++) 
        {
            scanf("%lld",&f[i]);
            a[1][i]=10;
            a[2][i]=1;
        }
        for(int i=3;i<=n+2;i++)
            for(int j=i;j<=n+2;j++) a[i][j]=1;
        qpow(a,m);
        mul1(f,a);
        printf("%lld\n",f[n+2]);
    }

}

 

發佈了74 篇原創文章 · 獲贊 4 · 訪問量 5051
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章