码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2018-10-19 23:45:47      阅读:203      评论:0      收藏:0      [点我收藏+]

标签:时间   pow   ast   can   快速   str   ace   org   ret   

传送门

解题思路

  以前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]迷路(矩阵乘法)

标签:时间   pow   ast   can   快速   str   ace   org   ret   

原文地址:https://www.cnblogs.com/sdfzsyq/p/9819278.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!