bzoj2396 神奇的矩阵
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2396
【题解】
我们随机一个1*n的矩阵D,根据矩阵乘法的结合律,如果A*B=C,右D*(A*B)=D*C,即(D*A)*B=C,那么矩阵乘法就是O(n^2)的复杂度了。
多随机几次即可。
# include <stdio.h> # include <string.h> # include <stdlib.h> # include <algorithm> // # include <bits/stdc++.h> using namespace std; typedef long long ll; typedef long double ld; typedef unsigned long long ull; inline int randi(int n) { return ((rand() << 15) + rand()) % n + 1; } int n; struct mat { int n, m, a[510][510]; inline void init (int _n, int _m) { n = _n, m = _m; memset(a, 0, sizeof a); } }A, B, C, o, tA, tB, tC; mat ta, tb, tc; inline void mul() { tc.init(ta.n, tb.m); for (int i=1; i<=tc.n; ++i) for (int j=1; j<=tc.m; ++j) for (int k=1; k<=ta.m; ++k) tc.a[i][j] = tc.a[i][j] + ta.a[i][k] * tb.a[k][j]; } int main() { while(~scanf("%d", &n)) { A.init(n, n); B.init(n, n); C.init(n, n); for (int i=1; i<=n; ++i) for (int j=1; j<=n; ++j) scanf("%d", &A.a[i][j]); for (int i=1; i<=n; ++i) for (int j=1; j<=n; ++j) scanf("%d", &B.a[i][j]); for (int i=1; i<=n; ++i) for (int j=1; j<=n; ++j) scanf("%d", &C.a[i][j]); for (int T = 1; T <= 10; ++T) { o.init(1, n); for (int i=1; i<=n; ++i) o.a[1][i] = randi(n); ta = o, tb = C; mul(); tC = tc; ta = o, tb = A; mul(); tA = tc; ta = tA, tb = B; mul(); tB = tc; for (int i=1; i<=n; ++i) if(tC.a[1][i] != tB.a[1][i]) { puts("No"); goto END; } } puts("Yes"); END:; } return 0; }