[luogu4159 SCOI2009] 迷路(矩陣乘法)
阿新 • • 發佈:2018-10-11
n) std 利用 efi ret etc main string stream
傳送門
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; }
[luogu4159 SCOI2009] 迷路(矩陣乘法)