1. 程式人生 > >食物(矩陣快速冪)(DP)

食物(矩陣快速冪)(DP)

技術 img ring 矩陣快速冪 快速 我們 long tps ret

技術分享圖片
這個題。。我們可以想到用遞推寫!!qwq(好吧,其實我的DP水平不高啊qwq)
然後我們看到數據範圍。。。好大呀qwq線性算法肯定會T啊qwq,那。。。。寫矩陣加速吧!qwq

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#define mod 1000000007
using namespace std;
int t;
int f[10];
struct Node{long long m[10][10];}node;
inline Node mul(Node x,Node y)
{
    Node cur;
    for(int i=1;i<=9;i++)
        for(int j=1;j<=9;j++)
            cur.m[i][j]=0;
    for(int i=1;i<=9;i++)
        for(int j=1;j<=9;j++)
            for(int k=1;k<=9;k++)
                cur.m[i][j]=(cur.m[i][j]+x.m[i][k]*y.m[k][j])%mod;
    return cur;
    
}
inline void solve(Node x)
{
    int cur[10];
    memset(cur,0,sizeof(cur));
    for(int j=1;j<=9;j++)
        for(int k=1;k<=9;k++)
            cur[j]=(cur[j]+f[k]*x.m[k][j])%mod;
    for(int i=1;i<=9;i++)
        f[i]=cur[i];
}
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        for(int i=1;i<=9;i++)
            for(int j=1;j<=9;j++)
                node.m[i][j]=0;
        node.m[1][4]=1,node.m[1][8]=1;
        node.m[2][1]=1,node.m[2][4]=1,node.m[2][8]=1;
        node.m[3][1]=1,node.m[3][4]=1;
        node.m[4][2]=1,node.m[4][5]=1,node.m[4][7]=1;
        node.m[5][2]=1,node.m[5][7]=1;
        node.m[6][2]=1,node.m[6][5]=1;
        node.m[7][6]=1,node.m[7][9]=1;
        node.m[8][3]=1,node.m[8][9]=1;
        node.m[9][3]=1,node.m[9][6]=1;
        memset(f,0,sizeof(f));
        int n;
        for(int i=1;i<=9;i++) f[i]=1;
        scanf("%d",&n);
        n-=2;
        while(n)
        {
            if(n&1) solve(node);
            node=mul(node,node);
            n>>=1;
        }
        long long ans=0;
        for(int i=1;i<=9;i++)
            ans=(ans+f[i])%mod;
        printf("%lld\n",ans%mod);
    }
    return 0;
}

食物(矩陣快速冪)(DP)