首先,题意就把我们引向了矩阵乘法,注意边长m<=60,那么就按边建图,变成一个120个点的图,然后乱搞就行了。
PS:WA了N久改了3次终于A了QAQ
CODE:
#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>#define mod 45989using namespace std;
struct mat{
int n,m;
long long a[122][122];
mat(){n=m=0;memset(a,0,sizeof(a));}
int I(int _x){n=m=_x;for (int i=1;i<=n;i++) a[i][i]=1;}
};mat operator *(const mat x,const mat y){
mat ans;
ans.n=x.n;ans.m=y.m;
for (int i=1;i<=x.n;i++)
for (int j=1;j<=y.m;j++)
for (int k=1;k<=x.m;k++)
(ans.a[i][j]+=x.a[i][k]*y.a[k][j])%=mod;
return ans;
}mat power(mat x,long long y){
mat ans;ans.I(x.n);
for (;y;y>>=1){
if (y&1) ans=ans*x;
x=x*x;
}
return ans;
}struct edges{
int id,to,next;
}edge[123];int l,next[23];
int addedge(int from,int to,int id){
edge[++l]=(edges){id,to,next[from]};
next[from]=l;
}int main(){
int n,m,a,b;
long long t;
mat x;
scanf("%d%d%lld%d%d",&n,&m,&t,&a,&b);
x.n=x.m=m*2;
a++;b++;
for (int i=1;i<=m;i++){
int x,y;
scanf("%d%d",&x,&y);
x++;y++;
addedge(x,y,i);
addedge(y,x,i+m);
}
for (int i=1;i<=n;i++)
for (int j=next[i];j;j=edge[j].next)
for (int k=next[edge[j].to];k;k=edge[k].next)
if (abs(edge[j].id-edge[k].id)!=m) x.a[edge[j].id][edge[k].id]=1;
x=power(x,t-1);
int q=t&1==1?1:0;
long long ans=0;
for (int i=next[a];i;i=edge[i].next)
for(int j=1;j<=l;j++) if (edge[j].to==b) (ans+=x.a[edge[i].id][edge[j].id])%=mod;
printf("%lld",ans);
return 0;
} |