(AB)(AB)(AB)=A(BA)(BA)B
用到线性代数的知识还是蛮有亲切感的。。毕竟上了大学就感觉这门课学到了东西。。
//#include<bits/stdc++.h> //#pragma comment(linker, "/STACK:1024000000,1024000000") #include<stdio.h> #include<algorithm> #include<queue> #include<string.h> #include<iostream> #include<math.h> #include<set> #include<map> #include<vector> #include<iomanip> using namespace std; const double pi=acos(-1.0); #define ll long long #define pb push_back #define sqr(a) ((a)*(a)) #define dis(a,b) sqrt(sqr(a.x-b.x)+sqr(a.y-b.y)) const double eps=1e-10; const int maxn=1e3+56; const int inf=0x3f3f3f3f; const ll mod=6; ll arr[maxn]; ll n,m; struct mat{ ll a[15][15]; ll n,m; mat(){memset(a,0,sizeof a);n=0;m=0;} mat(ll x,ll y){memset(a,0,sizeof a);n=x;m=y;} mat operator* (const mat &rhs)const{ mat ans; ans.n=n;ans.m=rhs.m; for(int i=1;i<=n;i++){ for(int j=1;j<=rhs.m;j++){ for(int k=1;k<=m;k++){ ans.a[i][j]=(ans.a[i][j]+a[i][k]*rhs.a[k][j])%mod; } } } return ans; } mat operator^ (ll rhs)const{ mat ans(n,n),b=*this; for(int i=1;i<=n;i++)ans.a[i][i]=1; for(;rhs;rhs>>=1,b=b*b) if(rhs&1)ans=ans*b; return ans; } }; ll a[maxn][maxn],b[maxn][maxn],c1[maxn][maxn],c2[maxn][maxn]; int main(){ while(~scanf("%lld%lld",&n,&m)&&n){ for(int i=1;i<=n;i++)for(int j=1;j<=m;j++) scanf("%lld",&a[i][j]); for(int i=1;i<=m;i++)for(int j=1;j<=n;j++) scanf("%lld",&b[i][j]); mat tmp(m,m); for(int i=1;i<=m;i++) for(int j=1;j<=m;j++){ tmp.a[i][j]=0; for(int k=1;k<=n;k++){ tmp.a[i][j]+=b[i][k]*a[k][j]; tmp.a[i][j]%=6; } } mat p=tmp^(n*n-1); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++){ c1[i][j]=0; for(int k=1;k<=m;k++){ c1[i][j]=(c1[i][j]+a[i][k]*p.a[k][j])%6; } } for(int i=1;i<=n;i++) for(int j=1;j<=n;j++){ c2[i][j]=0; for(int k=1;k<=m;k++){ c2[i][j]=(c2[i][j]+c1[i][k]*b[k][j])%6; } } ll ans=0; for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)ans+=c2[i][j]; printf("%lld ",ans); } }