AT_dp_rWalk
Posted Syara
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AT_dp_rWalk相关的知识,希望对你有一定的参考价值。
又是简单题。
我们知道弗洛伊德可以求解传递闭包。
我们有矩阵 \\(M\\),我们给 \\(M_k,i,j\\) 定义为 \\(i\\to j\\) 长度为 \\(k\\) 的路径数,细想不难发现有转移:
- \\(M_k,i,j=\\sum\\limits_p=1^n (M_k-1,i,p\\times M_1,p,j)\\)。
直接暴力弗洛伊德得到了 \\(kn^3\\) 的上天复杂度。
我们发现这实际就是矩阵乘法,\\(M_k=M_k-1\\times M_1\\)。
直接矩阵乘法即可——\\(M_k=M_1^k\\),结果为 \\(\\sum\\limits_i=1^n\\sum\\limits_j=1^n M_k,i,j\\)。
得到了 \\(O(n^3\\log k)\\) 的做法。
#include <stdio.h>
#include <string.h>
using namespace std;
int n;
long long k;
const int mod=1e9+7;
class Matrix
public:
long long s[105][105];
void input()
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%lld",&s[i][j]);
void output()
int ret=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
(ret+=s[i][j])%=mod;
printf("%d",ret);
ans,mid,a;
Matrix operator *(const Matrix& a,const Matrix& b)
memset(mid.s,0,sizeof mid.s);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
for(int k=1;k<=n;k++)
mid.s[i][j]+=a.s[i][k]*b.s[k][j];
mid.s[i][j]%=mod;
return(mid);
int main()
scanf("%d %lld",&n,&k);
a.input();
for(int i=1;i<=n;i++)ans.s[i][i]=1;
while(k>0)
if(k&1)ans=ans*a;
a=a*a;
k>>=1;
ans.output();
return(0);
以上是关于AT_dp_rWalk的主要内容,如果未能解决你的问题,请参考以下文章