@ysner
2018-07-31T17:04:20.000000Z
字数 1447
阅读 2650
DP 矩阵乘法 快速幂
号城市上有个机器人,有三种行为: 停在原地,去下一个相邻的城市,自爆。它每一秒都会随机触发一种行为。现 在给地图,在第秒时可乐机器人在号城市,问经过了秒,可乐机器人的行为方案数是多少?
显然可以。
设表示第秒到第点的方案数。
则有转移方程式:(点是点的邻点)
实际上,如果,此题仍然可做。
把图上信息转化为邻接矩阵。(间如有边则)
从角度来看,发现的第行第列数表示的是从到走步的路径方案数。
(同理,在另一种情况下可表示最短路径)
于是,中即为答案。
有点难度的是状态表示:
在原地停留:每个点都有一个从自己到自己的自环。
自爆:进入一个虚拟的、出不去的城市(如城市)。
注意要允许城市有自环,否则自爆的方案数就会乘消失。
// luogu-judger-enable-o2#include<iostream>#include<cmath>#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#define ll long long#define re register#define il inline#define max(a,b) ((a)>(b)?(a):(b))#define min(a,b) ((a)<(b)?(a):(b))#define fp(i,a,b) for(re int i=a;i<=b;i++)#define fq(i,a,b) for(re int i=a;i>=b;i--)using namespace std;const int N=105,mod=2017;int n,m,p,ans;struct Matrix{int a[105][105];Matrix operator *(Matrix b){Matrix c;memset(c.a,0,sizeof(c.a));fp(k,0,n)fp(i,0,n)fp(j,0,n)(c.a[i][j]+=a[i][k]*b.a[k][j]%mod)%=mod;return c;}}S,T;il ll gi(){re ll x=0,t=1;re char ch=getchar();while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();if(ch=='-') t=-1,ch=getchar();while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();return x*t;}int main(){n=gi();m=gi();fp(i,1,m){re int u=gi(),v=gi();T.a[u][v]=T.a[v][u]=1;T.a[u][0]=T.a[v][0]=1;T.a[u][u]=T.a[v][v]=1;}T.a[0][0]=1;p=gi();fp(i,0,n) S.a[i][i]=1;while(p){if(p&1) S=S*T;T=T*T;p>>=1;}fp(i,0,n) (ans+=S.a[1][i])%=mod;printf("%d\n",ans);return 0;}
