题目
https://www.luogu.org/problemnew/show/P2579
解题思路
注意题目说食人鱼的周期是2,3,4,所以它们的
l
c
m
lcm
lcm是
12
12
12周期。
根据巨佬的说法,
k
k
k既然那么大,显然矩阵乘法。
A
n
s
(
i
)
=
G
(
1
)
∗
G
(
2
)
∗
.
.
.
G
(
12
)
∗
G
(
1
)
∗
G
(
1
)
∗
G
(
2
)
∗
.
.
.
G
(
n
%
12
)
Ans(i)=G(1)*G(2)*...G(12)*G(1)*G(1)*G(2)*...G(n\%12)
Ans(i)=G(1)∗G(2)∗...G(12)∗G(1)∗G(1)∗G(2)∗...G(n%12)
我们可以先设矩阵
G
(
i
)
.
a
[
x
]
[
y
]
G(i).a[x][y]
G(i).a[x][y]为1,代表
x
x
x到
y
y
y之间在
i
i
i时刻可以行走。
然后根据题意,将某个时刻不能走的赋值为0即可。
最后套矩阵乘法模板,注意矩阵乘法不满足乘法交换律。
代码
#include<cstdio>
#include<algorithm>
#include<cstring>
#define rep(i,x,y) for(register int i=x;i<=y;++i)
using namespace std;
const int N=60,T=12,expectation=10000;
struct matrix{
int a[N][N];
}f[T],ans;
int n,m,start,end,k,nfish,w,e;
matrix operator * (matrix a,matrix b){
matrix c; memset(c.a,0,sizeof(c.a));
rep(i,0,N-1) rep(j,0,N-1) rep(g,0,N-1) (c.a[i][j]+=a.a[i][g]*b.a[g][j]%expectation)%=expectation;
return c;
}
int main(){
scanf("%d%d%d%d%d",&n,&m,&start,&end,&k);
rep(i,1,m) {
int x,y;
scanf("%d%d",&x,&y);
rep(j,0,T-1) f[j].a[x][y]=f[j].a[y][x]=1;
}
scanf("%d",&nfish);
rep(i,1,nfish){
scanf("%d",&w);
rep(j,0,w-1){
scanf("%d",&e);
for(register int g=j;g<T;g+=w){
int lq=(g-1<0)?T-1:g-1;
rep(q,0,n-1) f[lq].a[q][e]=0;
}
}
}
ans.a[0][start]=1;
matrix F=f[0];
rep(i,1,T-1) F=F*f[i];
int le=k/T;
for(;le;F=F*F,le>>=1) if (le&1) ans=ans*F;
rep(i,0,(k%T)-1) ans=ans*f[i];
printf("%d",ans.a[0][end]);
}