题目大意
计算 n * n 的矩阵 A 和 B 模3下的积。
思路
强算的复杂度为n^3,想办法用bitset优化。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <bitset>
#define INF 0x3f3f3f3f
#define rep0(i, n) for (int i = 0; i < n; i++)
#define rep1(i, n) for (int i = 1; i <= n; i++)
#define rep_0(i, n) for (int i = n - 1; i >= 0; i--)
#define rep_1(i, n) for (int i = n; i > 0; i--)
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#define mem(x, y) memset(x, y, sizeof(x))
#define MAXN 810
using namespace std;
bitset<MAXN> bs[MAXN], bs1[MAXN];
int A[MAXN][MAXN], B[MAXN][MAXN], n;
int C[MAXN][MAXN];
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif // ONLINE_JUDGE
while (scanf("%d", &n) != EOF)
{
for (int i = 0; i < n; i++)
{
bs[i].reset();
bs1[i].reset();
}
mem(C, 0);
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
scanf("%d", &A[i][j]);
A[i][j] %= 3;
if (A[i][j])
bs[i][j] = 1;
}
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
scanf("%d", &B[i][j]);
B[i][j] %= 3;
}
}
for (int j = 0; j < n; j++)
{
for (int i = 0; i < n; i++)
{
if (B[i][j])
bs1[j][i] = 1;
}
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
C[i][j] += (bs[i] & bs1[j]).count();
}
}
for (int i = 0; i < n; i++)
{
//bs[i].reset();
bs1[i].reset();
}
for (int j = 0; j < n; j++)
{
for (int i = 0; i < n; i++)
{
if (B[i][j] == 2)
bs1[j][i] = 1;
}
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
C[i][j] += (bs[i] & bs1[j]).count();
}
}
for (int i = 0; i < n; i++)
{
bs[i].reset();
//bs1[i].reset();
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
if (A[i][j] == 2)
bs[i][j] = 1;
}
}
for (int j = 0; j < n; j++)
{
for (int i = 0; i < n; i++)
{
if (B[i][j])
bs1[j][i] = 1;
}
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
C[i][j] += (bs[i] & bs1[j]).count();
C[i][j] %= 3;
}
}
for (int i = 0; i < n; i++)
{
//bs[i].reset();
bs1[i].reset();
}
for (int j = 0; j < n; j++)
{
for (int i = 0; i < n; i++)
{
if (B[i][j] == 2)
bs1[j][i] = 1;
}
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
C[i][j] += (bs[i] & bs1[j]).count();
C[i][j] %= 3;
}
}
for (int i = 0; i < n; i++)
{
printf("%d", C[i][0]);
for (int j = 1; j < n; j++)
printf(" %d", C[i][j]);
printf("\n");
}
}
return 0;
}
把 A 的每一行存为一个bitset,同理存B的每一列,但每个元素最大为2:
a1 = x1 + y1 a2 = x2 + y2
a1 = 2时,a1 = 1 + 1
a1 = 1时,a1 = 1 + 0 ...
a1 * a2 = (x1 + y1) * (x2 + y2) = x1 * x1 + x1 * y2 + y1 * x2 + y1 * y2
分解为 4 次bitset & 运算
也可以将矩阵分为两个bitset数组,一个记录1,一个记录2。