样例输入
3 2
1 2
3 4
5 6
10 10
-20 -20
30 30
6 5
4 3
2 1
4 0 -5
样例输出
480 240
0 0
-2200 -1100
答题
注意数值范围用int已经不行了,必须要用long long
而且矩阵运算涉及到三层循环,可以利用cache机制减少取值时间,先将右矩阵转置再计算
最关键的是由于d远远小于n,所以先计算KTV得到的dxd大小的矩阵要远远小于先计算QKT得到的nxn大小的矩阵,无论是存储上还是计算上都会大大减少时间
#include <iostream>
using namespace std;
long long** makeMatrix(int n,int d){
auto**p=new long long * [n];
for(long long i=0;i<n;i++){
p[i]=new long long[d];
}
return p;
}
void inputTurn(long long**p, int n, int d){
for(int i=0;i<n;i++)
for(int j=0;j<d;j++){
cin>>p[j][i];
}
}
int main(){
int n,d;
cin>>n>>d;
long long **Q= makeMatrix(n,d);
long long **K= makeMatrix(d,n);
long long **V= makeMatrix(d,n); // 利用cache将V转置存储
auto *W=new long long [n];
long long **result= makeMatrix(n,d);
for(int i=0;i<n;i++)
for(int j=0;j<d;j++){
cin>>Q[i][j];
}
inputTurn(K, n, d);
inputTurn(V, n, d);
for(int i=0;i<n;i++){
cin>>W[i];
}
long long **KTV= makeMatrix(d, d);
for(int i=0;i<d;i++)
for(int j=0;j<d;j++){
KTV[i][j]=0;
for(int k=0;k<n;k++){
KTV[i][j]+= K[i][k] * V[j][k];
}
}
for(int i=0;i<n;i++)
for(int j=0;j<d;j++){
result[i][j]=0;
for(int k=0;k<d;k++){
result[i][j]+= Q[i][k] * KTV[k][j];
}
}
for(int i=0;i<n;i++)
for(int j=0;j<d;j++){
result[i][j]*=W[i];
}
for(int i=0;i<n;i++){
for(int j=0;j<d-1;j++){
cout<<result[i][j]<<' ';
}
cout<<result[i][d-1]<<endl;
}
}