[关闭]
@ysner 2018-08-01T01:04:20.000000Z 字数 1447 阅读 2027

[TJOI2017]可乐

DP 矩阵乘法 快速幂


题面

号城市上有个机器人,有三种行为: 停在原地,去下一个相邻的城市,自爆。它每一秒都会随机触发一种行为。现 在给地图,在第秒时可乐机器人在号城市,问经过了秒,可乐机器人的行为方案数是多少?

解析

显然可以
表示第秒到第点的方案数。
则有转移方程式:(点是点的邻点)


记搜一下得
复杂度

实际上,如果,此题仍然可做。
把图上信息转化为邻接矩阵。(间如有边则)
角度来看,发现的第行第列数表示的是从步的路径方案数
(同理,在另一种情况下可表示最短路径)
于是,即为答案。

有点难度的是状态表示:

注意要允许城市有自环,否则自爆的方案数就会乘消失。

  1. // luogu-judger-enable-o2
  2. #include<iostream>
  3. #include<cmath>
  4. #include<cstdio>
  5. #include<cstdlib>
  6. #include<cstring>
  7. #include<algorithm>
  8. #define ll long long
  9. #define re register
  10. #define il inline
  11. #define max(a,b) ((a)>(b)?(a):(b))
  12. #define min(a,b) ((a)<(b)?(a):(b))
  13. #define fp(i,a,b) for(re int i=a;i<=b;i++)
  14. #define fq(i,a,b) for(re int i=a;i>=b;i--)
  15. using namespace std;
  16. const int N=105,mod=2017;
  17. int n,m,p,ans;
  18. struct Matrix
  19. {
  20. int a[105][105];
  21. Matrix operator *(Matrix b)
  22. {
  23. Matrix c;memset(c.a,0,sizeof(c.a));
  24. fp(k,0,n)
  25. fp(i,0,n)
  26. fp(j,0,n)
  27. (c.a[i][j]+=a[i][k]*b.a[k][j]%mod)%=mod;
  28. return c;
  29. }
  30. }S,T;
  31. il ll gi()
  32. {
  33. re ll x=0,t=1;
  34. re char ch=getchar();
  35. while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
  36. if(ch=='-') t=-1,ch=getchar();
  37. while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
  38. return x*t;
  39. }
  40. int main()
  41. {
  42. n=gi();m=gi();
  43. fp(i,1,m)
  44. {
  45. re int u=gi(),v=gi();
  46. T.a[u][v]=T.a[v][u]=1;
  47. T.a[u][0]=T.a[v][0]=1;
  48. T.a[u][u]=T.a[v][v]=1;
  49. }
  50. T.a[0][0]=1;
  51. p=gi();
  52. fp(i,0,n) S.a[i][i]=1;
  53. while(p)
  54. {
  55. if(p&1) S=S*T;
  56. T=T*T;
  57. p>>=1;
  58. }
  59. fp(i,0,n) (ans+=S.a[1][i])%=mod;
  60. printf("%d\n",ans);
  61. return 0;
  62. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注