LUOGU P4159 [SCOI2009]迷路(矩阵乘法)

Posted sdfzsyq

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LUOGU P4159 [SCOI2009]迷路(矩阵乘法)相关的知识,希望对你有一定的参考价值。

传送门

解题思路

  以前bpw讲过的一道题,顺便复习一下矩阵乘法。做法就是拆点,把每个点拆成(9)个点,然后挨个连边。之后若(i)(j)之间的边长度为(x),就让(i)的第(x)个点和(j)的第(1)个点连边。然后就是一个矩阵快速幂,时间复杂度(O((n*9)^3log(n*9)))

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>

using namespace std;
const int MAXN = 15;
const int MOD = 2009;
typedef long long LL;

int n,T,cnt;
LL ans;
char s[MAXN];

struct Matrix{
    int a[105][105];
    void Clear(){
        memset(a,0,sizeof(a));
    }
    friend Matrix operator*(const Matrix A,const Matrix B){
        Matrix C;C.Clear();
        for(register int i=1;i<=90;i++)
            for(register int j=1;j<=90;j++)
                for(register int k=1;k<=90;k++)
                    (C.a[i][j]+=((LL)A.a[i][k]*B.a[k][j]%MOD))%=MOD;
        return C;
    }
}mp,pre;

inline void fast_pow(Matrix x,int y){
    for(;y;y>>=1){
        if(y&1) pre=pre*x;
        x=x*x;
    }
}

int main(){
    int x;
    scanf("%d%d",&n,&T);cnt=n;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=8;j++)
            mp.a[(i-1)*9+j][(i-1)*9+j+1]=1;
    for(int i=1;i<=n;i++){
        scanf("%s",s+1);
        for(int j=1;j<=n;j++){
            x=s[j]-‘0‘;if(x==0) continue;
            mp.a[(i-1)*9+x][(j-1)*9+1]=1;
        }
    }
    pre.Clear();n=n*9;
    for(int i=1;i<=n;i++) pre.a[i][i]=1;
    fast_pow(mp,T);
    cout<<pre.a[1][n-8]<<endl;
    return 0;
}

以上是关于LUOGU P4159 [SCOI2009]迷路(矩阵乘法)的主要内容,如果未能解决你的问题,请参考以下文章

P4159 [SCOI2009] 迷路

P4159 [SCOI2009]迷路

[luogu4159 SCOI2009] 迷路(矩阵乘法)

[BZOJ 1297][SCOI2009]迷路

矩阵快速幂bzoj1297 [SCOI2009]迷路

[SCOI2009]迷路