正题
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4965
题目大意
给出矩阵A,BA,BA,B,求(AB)n(AB)^n(AB)n。然后对于每个元素%6\% 6%6后取和。
题目大意
我们发现如果直接让AB∗ABAB*ABAB∗AB这样的时间复杂度是n3n^3n3,显然不可过。但是我们注意到kkk特别小,所以我们可以将(AB)n∗n=A(BA)n∗n−1B(AB)^{n*n}=A(BA)^{n*n-1}B(AB)n∗n=A(BA)n∗n−1B
即可,然后时间复杂度就变为了O(n2k+k3logn)O(n^2k+k^3\ log\ n)O(n2k+k3 log n)
codecodecode
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int Size=10;
struct matrix{int a[Size][Size];
}c,ans,z;
int n,K,answer,B,Ans[1100][1100],a[1100][1100],b[1100][1100];
matrix operator*(matrix &a,matrix &b)
{memset(z.a,0,sizeof(z.a));for(int i=0;i<Size;i++)for(int j=0;j<Size;j++)for(int k=0;k<Size;k++)(z.a[i][j]+=a.a[i][k]*b.a[k][j])%=6;return z;
}
int main()
{while(scanf("%d%d",&n,&K)){if(n==0||K==0) return 0;B=n*n-2;memset(a,0,sizeof(a));memset(b,0,sizeof(b));memset(c.a,0,sizeof(c.a));memset(Ans,0,sizeof(Ans));answer=0;for(int i=0;i<n;i++)for(int j=0;j<K;j++)scanf("%d",&a[i][j]);for(int i=0;i<K;i++)for(int j=0;j<n;j++)scanf("%d",&b[i][j]);for(int i=0;i<K;i++)for(int j=0;j<K;j++)for(int k=0;k<n;k++)c.a[i][j]+=b[i][k]*a[k][j];ans=c;while(B){if(B&1) ans=ans*c;c=c*c;B>>=1;}for(int i=0;i<n;i++)for(int j=0;j<K;j++)for(int k=0;k<K;k++)Ans[i][j]+=a[i][k]*ans.a[k][j];for(int i=0;i<n;i++)for(int j=0;j<n;j++){int tmp=0;for(int k=0;k<K;k++)tmp+=Ans[i][k]*b[k][j];answer+=tmp%6;}printf("%d\n",answer);}
}