BZOj-1875: [SDOI2009]HH去散步 (矩阵快速幂)

Posted MichaelZona

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOj-1875: [SDOI2009]HH去散步 (矩阵快速幂)相关的知识,希望对你有一定的参考价值。

1875: [SDOI2009]HH去散步

Time Limit: 20 Sec  Memory Limit: 64 MB

Submit: 1999  Solved: 980

[​​Submit​​​][​​Status​​​][​​Discuss​​]

Description

HH有个一成不变的习惯,喜欢饭后百步走。所谓百步走,就是散步,就是在一定的时间 内,走过一定的距离。 但

是同时HH又是个喜欢变化的人,所以他不会立刻沿着刚刚走来的路走回。 又因为HH是个喜欢变化的人,所以他每

天走过的路径都不完全一样,他想知道他究竟有多 少种散步的方法。 现在给你学校的地图(假设每条路的长度都

是一样的都是1),问长度为t,从给定地 点A走到给定地点B共有多少条符合条件的路径

Input

第一行:五个整数N,M,t,A,B。

N表示学校里的路口的个数

M表示学校里的 路的条数

t表示HH想要散步的距离

A表示散步的出发点

B则表示散步的终点。

接下来M行

每行一组Ai,Bi,表示从路口Ai到路口Bi有一条路。

数据保证Ai != Bi,但不保证任意两个路口之间至多只有一条路相连接。 

路口编号从0到N -1。 

同一行内所有数据均由一个空格隔开,行首行尾没有多余空格。没有多余空行。 

答案模45989。

N ≤ 20,M ≤ 60,t ≤ 2^30,0 ≤ A,B

Output

一行,表示答案。

Sample Input

4 5 3 0 0
0 1
0 2
0 3
2 1
3 2

Sample Output

4

HINT

 

Source

​Day1​

laj一开始把题目看错了= = 不能走回头路哇……laj就说这题怎么可能这么傻逼呢……

然后就是很神的做法咯……把边存到矩阵里收尾相接的两条边在矩阵里连边,然后求t-1次幂,在开另一个矩阵,剩下的开代码qwq

laj又忘记膜辣……wa了一发 _(:зゝ∠)_

1 #include "bits/stdc++.h"
2 using namespace std;
3 typedef long long LL;
4 const int MAX=205,mod=45989;
5 int n,m,t,st,ed;
6 struct Mat
7 int x,y;
8 int mat[MAX][MAX];
9 Mat()x=y=0;memset(mat,0,sizeof(mat));
10 friend Mat operator * (Mat cc,Mat tt)
11 Mat an;int i,j,k;
12 an.x=cc.x,an.y=tt.y;
13 for (i=1;i<=cc.x;i++)
14 for (k=1;k<=cc.y;k++)
15 if (cc.mat[i][k])
16 for (j=1;j<=an.y;j++)
17 an.mat[i][j]=(an.mat[i][j]+cc.mat[i][k]*tt.mat[k][j])%mod;
18 return an;
19
20 friend Mat operator ^(Mat cc,int tt)
21 Mat an;int i,j;
22 an.x=cc.x,an.y=cc.y;
23 for (i=1;i<=cc.x;i++) an.mat[i][i]=1;
24 while (tt)
25 if (tt&1) an=an*cc;
26 cc=cc*cc,tt>>=1;
27
28 return an;
29
30 void out()
31 int i,j;
32 for (i=1;i<=x;i++)
33 for (j=1;j<=y;j++)
34 printf("%d ",mat[i][j]);
35 printf("\\n");
36
37 printf("\\n");
38
39 a,b;
40 struct Edgeint x,y;edge[1005];
41 int tot,head[MAX],adj[1005],next[1005];
42 void addedge(int u,int v)tot++;adj[tot]=v,next[tot]=head[u],head[u]=tot,edge[tot].x=u,edge[tot].y=v;
43 inline int read()
44 int an=0,x=1;char c=getchar();
45 while (c<0 || c>9) if (c==-) x=-1;c=getchar();
46 while (c>=0 && c<=9) an=(an<<3)+(an<<1)+c-0;c=getchar();
47 return an*x;
48
49 int main()
50 freopen ("walk.in","r",stdin);freopen ("walk.out","w",stdout);
51 int i,j,x,y;tot=1;
52 n=read(),m=read(),t=read(),st=read(),ed=read();st++,ed++;
53 for (i=1;i<=m;i++)
54 x=read(),y=read();x++,y++;
55 addedge(x,y),addedge(y,x);
56
57 a.x=a.y=b.x=b.y=tot;
58 for (i=head[st];i;i=next[i]) a.mat[1][i]++;
59 for (i=2;i<=tot;i++)
60 for (j=2;j<=tot;j++)
61 if (edge[i].y==edge[j].x && i!=(j^1))
62 b.mat[i][j]++;
63 a=a*(b^(t-1));
64 int ans=0;
65 for (i=head[ed];i;i=next[i])
66 ans+=a.mat[1][i^1];
67 printf("%d",ans%mod);
68 return 0;
69

 

以上是关于BZOj-1875: [SDOI2009]HH去散步 (矩阵快速幂)的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ 1875SDOI 2009HH去散步

bzoj 1875: [SDOI2009]HH去散步 -- 矩阵乘法

BZOj-1875: [SDOI2009]HH去散步 (矩阵快速幂)

BZOj-1875: [SDOI2009]HH????????? (???????????????)

bzoj 1875 [SDOI2009]HH去散步(矩乘)

bzoj1875 [SDOI2009]HH去散步——矩阵快速幂