[题解]luogu_P4159_迷路(矩阵floyd

前言:(好久没写了)9102年苹果竟然发布了18W快充 终于赶上了国产千元机水平!业界良心啊!购买充电器只要区区243元!购买长达2m的超长充电线只要在加272元就可以了!大家觉得这个价格怎么样呢 新款iPhone pro所使用的令人惊叹的全新设计竟是三个煤气灶比2080ti竟然还多一个孔1200w像素摄像头 没有再加入一个200w像素摄像头组成四摄多卖一千块更加业界良心其实等着明年挤牙膏(以上内容其实来自科技美学

看了无主之地3媒体试玩虽然我是魔女爱好者但是我选赞恩


 

早就讲过的题,还是非常好的

我们知道如果边权只为1和0可以用floyd和矩阵快速幂算出方案数

但是这里边权为1~9,其实也非常小

所以我们可以把点拆成9个点,之间边权为1,某点对此点边权为几就向此点的第几个点连边,这样就可以floyd了

#include<bits/stdc++.h>

using namespace std;
const int maxn=109;
const int mod=2009;
int n,m,t;
struct node{
    int a[maxn][maxn];
    node(){}
    void clear(){
        memset(a,0,sizeof(a));
    }
    node operator *(const node &t)const{
        node ans;ans.clear();
        for(int i=1;i<=m;i++)
        for(int j=1;j<=m;j++)
        for(int k=1;k<=m;k++)
        ans.a[i][j]=(ans.a[i][j]+a[i][k]*t.a[k][j])%mod;
        return ans;
    }
}f;
node operator ^(node a,int b){
    node ans;ans.clear();
    for(int i=1;i<=m;i++)ans.a[i][i]=1;
    while(b){
        if(b&1)ans=ans*a;
        a=a*a;
        b>>=1;
    }
    return ans;
}
char s[maxn][maxn];
int hsh(int x,int y){
    return x+y*n;
}
int main(){
    scanf("%d%d",&n,&t);m=n*9;
    for(int i=1;i<=n;i++)scanf("%s",s[i]+1);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=8;j++)
        f.a[hsh(i,j)][hsh(i,j-1)]=1;
        for(int j=1;j<=n;j++)
        f.a[i][j+(s[i][j]-'0'-1)*n]=1;
    }
    f=f^t;
    printf("%d\n",f.a[1][n]);
}

 

posted @ 2019-09-11 09:32  羊肉汤泡煎饼  阅读(122)  评论(0编辑  收藏  举报