您的位置:首页 > 其它

bzoj1297: [SCOI2009]迷路

2017-04-18 18:12 267 查看
传送门

T这么大,N这么小,普通做法绝对T。

但我们发现每一次转移方式相同。

于是考虑矩乘。

我们可以先拆点,将一个点化为9个,状态是(位置,时间)

注意,虽然他们可能还在路上,但是我们可以连到时间为k-1的地方,连权值为1的边。

同一个店时间相差1的连边。

答案就是f[S][T]

#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<queue>
#define mo 2009
#define N 90
using namespace std;
struct matrix{
int a[N+5][N+5];
matrix operator * (const matrix &b) const{
matrix c;
for (int i=1;i<=N;i++)
for (int j=1;j<=N;j++){
c.a[i][j]=0;
for (int k=1;k<=N;k++)
c.a[i][j]=(c.a[i][j]+a[i][k]*b.a[k][j])%mo;
}
return c;
}
}x,y;
int n,t;
char s[15];
void quick(int t){
if (t==1) return;
quick(t/2);
y=y*y;
if (t%2) y=y*x;
}
int main(){
scanf("%d%d",&n,&t);
for (int i=0;i<n;i++){
scanf("%s",&s);
for (int j=0;j<n;j++)
if (s[j]!='0')
x.a[i*9+1][j*9+s[j]-48]=1;
}
for (int i=0;i<n;i++)
for (int j=1;j<9;j++) x.a[i*9+j+1][i*9+j]=1;
y=x;
quick(t);
printf("%d",y.a[1][n*9-8]);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: