[BZOJ1297/Luogu4159][SCOI2009]迷路
生活随笔
收集整理的這篇文章主要介紹了
[BZOJ1297/Luogu4159][SCOI2009]迷路
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目鏈接:
BZOJ1297
Luogu4159
首先考慮距離只有\(0,1\)的情況
那么如果設\(f[t][i][j]\)表示\(i\)到\(j\)走\(t\)時刻的方案數,有轉移方程:
\(f[t][i][j]=\sum f[t-1][i][k]*f[t-1][j][k]\)
如果把\(f[t]\)看成一個\(n*n\)的矩陣就是\(f[t]=f[t-1]*f[t-1]\)
那么就可以矩陣快速冪。
現在考慮距離更大的情況:
若有一條距離為\(x\)的邊\((i,j)\),那么可以把它拆成\(x\)條長度為\(1\)的邊
對每一個點建一些“虛點”,\(P(i,1)\)代表\(i\),\(P(i,j)(j>1)\)代表\(i\)的其他虛點,那么就將\(P(i,1),P(i,2),\cdots,P(i,x)\)連上邊,再連上\(P(i,x),P(j,1)\)即可。
矩陣忘記初始化。。調了1h+。。。
時間復雜度 \(O((9n)^3log_2t)\)
代碼:
#include <cstdio> #include <cstring> #define Pos(i,j) (((i)-1)*9+(j))int n,m,t; struct Matrix{int a[105][105];Matrix(){memset(a,0,sizeof a);}}f;inline Matrix operator*(const Matrix &a,const Matrix &b) {Matrix Res;for(register int i=1;i<=m;++i)for(register int k=1;k<=m;++k)for(register int j=1;j<=m;++j)Res.a[i][j]=(Res.a[i][j]+a.a[i][k]*b.a[k][j])%2009;return Res; }inline Matrix operator^(Matrix Bas,int x) {Matrix Res;for(int i=1;i<=m;++i)Res.a[i][i]=1;for(;x;x>>=1,Bas=Bas*Bas)if(x&1)Res=Res*Bas;return Res; }int main() {scanf("%d%d",&n,&t),m=n*9;for(int i=1;i<=n;++i){for(int j=1;j<9;++j)f.a[Pos(i,j)][Pos(i,j+1)]=1;for(int j=1,d;j<=n;++j)if(scanf("%1d",&d),d)f.a[Pos(i,d)][Pos(j,1)]=1;}Matrix Res=f^t;printf("%d\n",Res.a[Pos(1,1)][Pos(n,1)]);return 0; }轉載于:https://www.cnblogs.com/LanrTabe/p/10513300.html
總結
以上是生活随笔為你收集整理的[BZOJ1297/Luogu4159][SCOI2009]迷路的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 架构-浅谈MySQL数据库优化
- 下一篇: olive videoeditor开源跨