Analysis
由于ti很小,我们可以将每个点都拆成若干个点然后就将边权不为1转化为边权为1了
即将图中的每个点拆成至多9个点,首先将每个点的第i个点和第i+1个点连一条权值为1的边。另外,如果原图中Eij=m,则将新图的第i个点拆成的第m点和j点的第一个点连一条权值为1的边。这样就完全转化为我们可以解决的问题形式了。
时间复杂度 O(n’^3*logT)
Code
#include<bits/stdc++.h>
#define in read()
#define re register
using namespace std;
inline int read(){
char ch;int f=1,res=0;
while((ch=getchar())<'0'||ch>'9') if(ch=='-') f=-1;
while(ch>='0'&&ch<='9'){
res=(res<<1)+(res<<3)+(ch^48);
ch=getchar();
}
return f==1?res:-res;
}
#define MOD 2009
struct matrix{
int a[105][105];
matrix(int t=0){
memset(a,0,sizeof(a));
for(re int i=1;i<=100;++i)
a[i][i]=t;
}
inline matrix operator *(const matrix &A){
matrix ans(0);
for(re int i=1;i<=100;++i)
for(re int j=1;j<=100;++j)
for(re int k=1;k<=100;++k)
ans.a[i][j]=(ans.a[i][j]+a[i][k]*A.a[k][j]%MOD)%MOD;
return ans;
}
inline friend matrix operator ^(matrix A,int b){
matrix ans(1);
while(b){
if(b&1) ans=ans*A;
A=A*A;
b>>=1;
}
return ans;
}
}A;
int n,T;
char st[15];
int main(){
n=in;T=in;
for(re int i=1;i<=n;++i){
for(re int j=1;j<=8;++j) A.a[(i-1)*9+j][(i-1)*9+j+1]=1;
scanf("%s",st);
for(re int j=0;j<n;++j){
int z=st[j]-'0';
if(!z) continue;
A.a[(i-1)*9+z][j*9+1]=1;
}
}
A=A^T;
printf("%d",A.a[1][(n-1)*9+1]);
return 0;
}