问题即求$\sum_{i=0}^{d}(out\cdot in)^{d}_{u,v}$,进而转换为$[u=v]+(out\cdot \sum_{i=0}^{d-1}(in\cdot out)^{i}\cdot in)_{u,v}$
注意到$in\cdot out$是$k\times k$的,并使用类似矩阵快速幂的方式计算幂次前缀和即可
时间复杂度为$o(nk^{2}+qk^{3}\log d)$,可以通过
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define N 1005 4 #define M 25 5 #define mod 1000000007 6 #define ll long long 7 int n,m,q,x,y,z,ans,out[N][M],in[M][N],st[N]; 8 struct mat{ 9 int a[M][M]; 10 mat(int p=0){ 11 memset(a,0,sizeof(a)); 12 for(int i=1;i<=m;i++)a[i][i]=p; 13 } 14 }a,s,sum; 15 mat add(mat &a,mat b){ 16 mat ans; 17 for(int i=1;i<=m;i++) 18 for(int j=1;j<=m;j++)ans.a[i][j]=(a.a[i][j]+b.a[i][j])%mod; 19 return ans; 20 } 21 mat mul(mat &a,mat &b){ 22 mat ans; 23 for(int i=1;i<=m;i++) 24 for(int j=1;j<=m;j++) 25 for(int k=1;k<=m;k++)ans.a[i][k]=(ans.a[i][k]+(ll)a.a[i][j]*b.a[j][k])%mod; 26 return ans; 27 } 28 int main(){ 29 scanf("%d%d",&n,&m); 30 for(int i=1;i<=n;i++){ 31 for(int j=1;j<=m;j++)scanf("%d",&out[i][j]); 32 for(int j=1;j<=m;j++)scanf("%d",&in[j][i]); 33 } 34 for(int i=1;i<=m;i++) 35 for(int j=1;j<=n;j++) 36 for(int k=1;k<=m;k++)a.a[i][k]=(a.a[i][k]+(ll)in[i][j]*out[j][k])%mod; 37 scanf("%d",&q); 38 while (q--){ 39 scanf("%d%d%d",&x,&y,&z); 40 for(;z;z>>=1)st[++st[0]]=(z&1); 41 s=1,sum=0; 42 while (st[0]){ 43 sum=add(sum,mul(s,sum)),s=mul(s,s); 44 if (st[st[0]])sum=add(s,sum),s=mul(s,a); 45 st[0]--; 46 } 47 ans=(x==y); 48 for(int i=1;i<=m;i++) 49 for(int j=1;j<=m;j++)ans=(ans+(ll)out[x][i]*sum.a[i][j]%mod*in[j][y])%mod; 50 printf("%d\n",ans); 51 } 52 return 0; 53 }