https://judgegirl.csie.org/problem/0/10122
稀疏矩陣為大部份元素皆為零的矩陣,在科學與工程領域中求解線性模型時經常出現大型的稀疏矩陣。現在給予最常見的 Coordinate Format (簡稱 COO 格式),請問兩個矩陣相乘結果為何。給予矩陣 An,m 和 Bm,r,請計算稀疏矩陣相乘。
因为最近需要重写一下tensorflow里面的稀疏矩阵和稠密矩阵乘法(还没看懂),所以先学习一下稀疏矩阵乘法,稀疏矩阵乘法和一般的矩阵乘法很相似,只需要额外根据矩阵的行号列号找到对应的三元组即可,这块用二分,如果找不到说明那块是0。
#include<stdio.h>
#define ul unsigned long
#define N 1000010
int n, m, r;
int na, nb;
typedef struct node{
int row, col;
ul val, idx;
}node;
node A[N], B[N];
ul rotate_left(ul x, ul n) {
return (x << n) | (x >> (32 - n));
}
ul encrypt(ul m, ul key) {
return (rotate_left(m, key & 31) + key) ^ key;
}
int find(ul x, node m[N], int len){
int l = 0, r = len - 1;
while(l < r){
int mid = l + r + 1 >> 1;
if(m[mid].idx <= x) l = mid;
else r = mid - 1;
}
if(m[l].idx != x) return -1;
return l;
}
int main(){
scanf("%d%d%d%d%d", &n, &m, &r, &na, &nb);
for(int i = 0; i < na; i ++){
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
A[i].row = a, A[i].col = b, A[i].val = c, A[i].idx = (ul) a * m + b;
}
for(int i = 0; i < nb; i ++){
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
B[i].row = a, B[i].col = b, B[i].val = c, B[i].idx = (ul) a * r + b;
}
ul res = 0;
for(int i = 0; i < n; i ++)
for(int j = 0; j < r; j ++){
ul sum = 0;
for(int k = 0; k < m; k ++){
int idx_a = find((ul) m * i + k, A, na), idx_b = find((ul) r * k + j, B, nb);
if(~idx_a && ~idx_b) sum += A[idx_a].val * B[idx_b].val;
}
if(sum) res += encrypt((i + 1) * (j + 1), sum);
}
printf("%u", res);
return 0;
}
复杂度:\(O(nmr)\)并不是最优的,但是本题由于三元组的个数也达到1e6所以也优化不到哪去
另外就是原题要求用是intel的编译器,网站上貌似关掉了