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


    传送门

    Solution

    矩阵乘法新姿势qwq
    我们知道当边权为1是我们可以利用矩阵快速幂来方便的求出路径数
    那么对于边权很小的时候,我们可以将每个点都拆成若干个点
    然后就将边权不为1转化为边权为1了

    Code

    //By Menteur_Hxy
    #include <queue>
    #include <cmath>
    #include <cstdio>
    #include <vector>
    #include <cstring>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    #define Re register 
    #define Ms(a,b) memset(a,(b),sizeof(a))
    #define Fo(i,a,b) for(Re int i=(a),_=(b);i<=_;i++)
    #define Ro(i,a,b) for(Re int i=(b),_=(a);i>=_;i--)
    using namespace std;
    typedef long long LL;
    typedef pair<int,int> PII;
    
    inline LL read() {
    	LL x=0,f=1;char c=getchar();
    	while(!isdigit(c)) {if(c=='-')f=-f;c=getchar();}
    	while(isdigit(c)) x=(x<<1)+(x<<3)+c-48,c=getchar();
    	return x*f;
    }
    
    const int N=11,MOD=2009;
    int n,T;
    char s[N];
    struct Matrix{
    	int da[N*10][N*10];
    	Matrix() {Ms(da,0);}
    	void init() {Fo(i,1,n*10)da[i][i]=1;}
    	Matrix operator * (const Matrix &oth) const {
    		Matrix res;
    		Fo(i,1,n*10) Fo(j,1,n*10) Fo(k,1,n*10) 
    			res.da[i][j]+=da[i][k]*oth.da[k][j]%MOD,res.da[i][j]%=MOD;
    		return res;
    	}
    }mat;
    
    Matrix Qpow(Matrix a,int b) {
    	Matrix res; res.init();
    	while(b) {
    		if(b&1) res=res*a;
    		a=a*a; b>>=1;
    	}
    	return res;
    }
    
    inline int id(int x,int y) {return x*n+y-n;}
    
    int main() {
    	n=read(),T=read();
    	Fo(i,1,n) {
    		scanf("%s",s+1);
    		Fo(j,1,n) mat.da[id(9-s[j]+'0'+1,i)][id(9,j)]++;
    	}
    	Fo(i,1,8) Fo(j,1,n) mat.da[id(i+1,j)][id(i,j)]++;
     	mat=Qpow(mat,T);
    	printf("%d",mat.da[id(9,1)][id(9,n)]);
    	return 0;
    }
    
  • 相关阅读:
    go语言——strings和strconv
    go语言——map
    Manjaro配置
    go语言——数组和切片
    go语言——随机数
    go——选择和循环
    go语言——输入输出
    java动态代理实现--基于子类的动态代理
    java动态代理实现--基于接口的动态代理
    spring依赖注入
  • 原文地址:https://www.cnblogs.com/Menteur-Hxy/p/9773737.html
Copyright © 2020-2023  润新知