广告:
#include <stdio.h>
int main()
{
puts("转载请注明出处[vmurder]谢谢");
puts("网址:blog.csdn.net/vmurder/article/details/44101165");
}
题解:
食人鱼循环2、3、4,lcm=12。
所以12次转移为一组,这么进行快速幂矩乘,最后把余数那几次转移乘上。
代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define T 55
#define mod 10000
using namespace std;
struct MRX
{
int x[T][T];
}Trs[13],Ini,Std,E;
int s,t,n,m,p,q;
MRX mul(const MRX &a,const MRX &b)
{
MRX c=E;
int i,j,k;
for(i=0;i<n;i++)for(j=0;j<n;j++)for(k=0;k<n;k++)
c.x[i][j]=(c.x[i][j]+a.x[i][k]*b.x[k][j])%mod;
return c;
}
MRX power(MRX x,int k)
{
MRX ans=Std;
while(k)
{
if(k&1)ans=mul(ans,x);
x=mul(x,x),k>>=1;
}
return ans;
}
int pos[5];
int main()
{
freopen("test.in","r",stdin);
int i,j,k;
int a,b;
scanf("%d%d%d%d%d",&n,&m,&s,&t,&p);
for(i=0;i<n;i++)Std.x[i][i]=1;
for(i=1;i<=m;i++)
{
scanf("%d%d",&a,&b);
for(j=1;j<=12;j++)Trs[j].x[a][b]++,Trs[j].x[b][a]++;
}
Trs[0]=Std;
scanf("%d",&q);
while(q--)
{
scanf("%d",&k);
for(j=1;j<=k;j++)scanf("%d",&pos[j]);
if(pos[1]==s||pos[p%k+1]==t)
{
puts("0");
return 0;
}
for(j=0;j<k;j++)pos[j]=pos[j+1];
for(j=1;j<=12;j++)
{
a=(j-1)%k;
for(i=0;i<n;i++)
Trs[j].x[pos[a]][i]=0;
}
}
for(i=1;i<=12;i++)Trs[0]=mul(Trs[0],Trs[i]);
Trs[0]=power(Trs[0],p/12),p%=12;
Ini.x[0][s]=1,Ini=mul(Ini,Trs[0]);
for(i=1;i<=p;i++)Ini=mul(Ini,Trs[i]);
printf("%d\n",Ini.x[0][t]);
return 0;
}
时间: 2024-10-11 11:10:44