Description
学过线性代数后,Ocean又有了新的难题。
现在Ocean有两个矩阵AA和BB,大小分别为n∗x和x∗m。现在Ocean想知道新矩阵C=(A∗B)t。
但是输出矩阵太麻烦了,你只需要告诉他CC矩阵元素之和对666取余的结果即可。
所有测试数据保证n 等于 m。请认真读题
Input
第一行输入一个整数TT,代表有TT组测试数据。
每组数据占多行,第一行依次输入四个整数n,x,m,tn,x,m,t分别代表上面提到的信息。
接下来有nn行,每行输入xx个元素代表AA矩阵。
后面再有xx行,每行输入mm个元素代表BB矩阵。
注:1<=T<=100,1<=n,m,t<=1000,1<=x<=6,1<=1<=T<=100,1<=n,m,t<=1000,1<=x<=6,1<=矩阵元素 <=66。
Output
输出一个整数,代表CC矩阵元素之和对666666取余后的结果
Sample Input
2
10 3 10 1000
1 1 1
1 1 1
1 1 1
1 1 1
1 1 1
1 1 1
1 1 1
1 1 1
1 1 1
1 1 1
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2
10 4 10 1000
1 2 3 4
1 2 3 4
1 2 3 4
1 2 3 4
1 2 3 4
1 2 3 4
1 2 3 4
1 2 3 4
1 2 3 4
1 2 3 4
7 7 7 7 7 7 7 7 7 7
7 7 7 7 7 7 7 7 7 7
7 7 7 7 7 7 7 7 7 7
7 7 7 7 7 7 7 7 7 7
Sample Output
396
340
Hint
题意
题解:
先求B*A 这样快速幂复杂度降很多 因为B*A的矩阵边长只有x
即A*(B*A)^t*B
AC代码
#include <cstdio>
#include <cstring>
const int mod = 666;
struct mat{
int rix[15][15];
};
int aa[1005][15];
int bb[15][1005];
int lt[1005][15];
int ans[1005][1005];
int n,m,x;
mat mul(mat a,mat b){
mat c;
for (int i = 0;i < x; ++i) for (int j = 0;j < x; ++j) c.rix[i][j] = 0;
for (int i = 0;i < x; ++i){
for (int j = 0; j < x; ++j){
for (int k = 0;k < x; ++k){
c.rix[i][j] += a.rix[i][k]*b.rix[k][j];
c.rix[i][j] %= mod;
}
}
}
return c;
}
mat q_mod(mat a,int b){
mat tmp;
for (int i = 0;i < x; ++i) for (int j = 0;j < x; ++j) tmp.rix[i][j] = (i==j);
while (b){
if (b&1) tmp = mul(tmp,a);
a = mul(a,a);
b>>=1;
}
return tmp;
}
int main(){
int t;
scanf("%d",&t);
while (t--){
memset(aa,0,sizeof(aa));
memset(bb,0,sizeof(bb));
memset(lt,0,sizeof(lt));
memset(ans,0,sizeof(ans));
int tt;
scanf("%d%d%d%d",&n,&x,&m,&tt);
for (int i = 0;i < n; ++i) for (int j = 0;j < x; ++j) scanf("%d",&aa[i][j]);
for (int i = 0;i < x; ++i) for (int j = 0;j < m; ++j) scanf("%d",&bb[i][j]);
mat st;
for (int i = 0;i < x; ++i) for (int j = 0;j < x; ++j) st.rix[i][j] = 0;
for (int i = 0;i < x; ++i) for (int j = 0;j < x; ++j) for (int k = 0;k < m; ++k){
st.rix[i][j] += bb[i][k]*aa[k][j];
st.rix[i][j] %= mod;
}
mat ed;
ed = q_mod(st,tt-1);
for (int i = 0;i < n; ++i) for (int j = 0;j < x; ++j) for (int k = 0;k < x; ++k){
lt[i][j] += aa[i][k]*ed.rix[k][j];
lt[i][j] %= mod;
}
for (int i = 0;i < n; ++i) for (int j = 0;j < m; ++j) for (int k = 0;k < x; ++k){
ans[i][j] += lt[i][k]*bb[k][j];
ans[i][j] %= mod;
}
int sum = 0;
for (int i = 0;i < n; ++i) for(int j = 0;j < m; ++j) sum=(sum+ans[i][j])%mod;
printf("%d\n",sum);
}
return 0;
}