QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#317996 | #7612. Matrix Inverse | nhuang685 | RE | 0ms | 0kb | C++20 | 7.3kb | 2024-01-30 10:03:52 | 2024-01-30 10:03:53 |
answer
/**
* @file qoj7612-1.cpp
* @author n685
* @brief
* @date 2024-01-29
*
*
*/
#include <bits/stdc++.h>
#ifdef LOCAL
#include "dd/debug.h"
#else
#define dbg(...) 42
#define dbgR(...) 4242
#define dbgP(...) 420
#define dbgRP(...) 420420
void nline() {}
#endif
template <class T> constexpr std::pair<T, T> exEucl(T a, T b) {
if (a < b) {
// auto [x, y] = exEucl(b, a);
T x, y;
std::tie(x, y) = exEucl(b, a);
return {y, x};
}
if (b == 0) {
assert(a == 1);
return {1, 0};
}
// auto [x, y] = exEucl(b, a % b);
T x, y;
std::tie(x, y) = exEucl(b, a % b);
return {y, x - (a / b) * y};
}
template <
class T, class U,
typename std::enable_if<std::is_integral<U>::value, bool>::type = true>
constexpr T binpow(T a, U b) {
// 0^0 = 1
T res = 1;
while (b > 0) {
if (b % 2 == 1) {
res *= a;
}
a *= a;
b /= 2;
}
return res;
}
template <class Md, class V = int64_t> struct Mod {
using T = typename std::decay<decltype(Md::value)>::type;
T val = 0;
template <class U> static constexpr T normalize(U val) {
if (val <= -Md::value || Md::value <= val) {
val %= Md::value;
}
if (val < 0) {
val += Md::value;
}
return static_cast<T>(val);
}
constexpr Mod() : val(0) {}
template <class U, typename std::enable_if<std::is_integral<U>::value,
bool>::type = true>
constexpr Mod(U _val) {
val = normalize(_val);
}
// addition
constexpr Mod &operator+=(Mod b) {
val += b.val;
if (val >= Md::value) {
val -= Md::value;
}
return *this;
}
friend constexpr Mod operator+(Mod a, Mod b) { return (a += b); }
constexpr Mod &operator++() { return (*this += 1); }
constexpr Mod operator++(int) {
Mod res = *this;
++(*this);
return res;
}
// subtraction
constexpr Mod &operator-=(Mod b) {
val -= b.val;
if (val < 0) {
val += Md::value;
}
return *this;
}
friend constexpr Mod operator-(Mod a, Mod b) { return (a -= b); }
constexpr Mod &operator--() { return (*this -= 1); }
constexpr Mod operator--(int) {
Mod res = *this;
--(*this);
return res;
}
// multiplication
constexpr Mod &operator*=(Mod b) {
val = static_cast<T>(static_cast<V>(val) * b.val % Md::value);
return *this;
}
friend constexpr Mod operator*(Mod a, Mod b) { return (a *= b); }
template <class U> constexpr Mod binpow(U b) const {
return ::binpow(*this, b);
}
constexpr Mod inv() const {
return Mod(exEucl(static_cast<V>(val), static_cast<V>(Md::value)).first);
// return binpow(Md::value - 2);
}
// comparison
constexpr bool operator==(Mod b) const { return (val == b.val); }
// constexpr auto operator<=>(const Mod &b) const = default;
constexpr bool operator!=(Mod b) const { return (val != b.val); }
constexpr bool operator<(Mod b) const { return (val < b.val); }
constexpr bool operator>(Mod b) const { return (val > b.val); }
constexpr bool operator<=(Mod b) const { return (val <= b.val); }
constexpr bool operator>=(Mod b) const { return (val >= b.val); }
// io
friend std::istream &operator>>(std::istream &in, Mod &a) {
V v;
in >> v;
a = Mod(v);
return in;
}
friend std::ostream &operator<<(std::ostream &out, const Mod &a) {
out << a.val;
return out;
}
// conversion
explicit constexpr operator T() const { return val; }
constexpr const T &operator()() const { return val; }
constexpr Mod operator-() const { return Mod(-val); }
};
constexpr int MOD = (int)1e9 + 7;
using Mint = Mod<std::integral_constant<std::decay<decltype(MOD)>::type, MOD>>;
using Row = std::vector<Mint>;
Row operator+=(Row &a, Row b) {
for (int i = 0; i < (int)a.size(); ++i) {
a[i] += b[i];
}
return a;
}
Row operator+(Row a, Row b) { return (a += b); }
Row operator-=(Row &a, Row b) {
for (int i = 0; i < (int)a.size(); ++i) {
a[i] -= b[i];
}
return a;
}
Row operator-(Row a, Row b) { return (a -= b); }
Row operator*=(Row &a, Mint b) {
for (int i = 0; i < (int)a.size(); ++i) {
a[i] *= b;
}
return a;
}
Row operator*(Row a, Mint b) { return a *= b; }
Row operator*(Mint b, Row a) { return a *= b; }
std::vector<Mint> gauss(std::vector<Row> eq) {
int n = (int)eq.size();
int m = (int)eq[0].size() - 1;
for (int i = 0; i < m; ++i) {
int ind = i;
while (ind < n && eq[ind][i] == 0) {
++ind;
}
if (ind == n) {
return {};
}
std::swap(eq[i], eq[ind]);
eq[i] *= eq[i][i].inv();
for (int j = 0; j < n; ++j) {
if (j != i) {
eq[j] -= eq[j][i] * eq[i];
}
}
}
std::vector<Mint> sol(m);
for (int i = 0; i < m; ++i) {
sol[i] = eq[i].back();
}
return sol;
}
int main() {
#ifdef LOCAL
std::freopen("input.txt", "r", stdin);
std::freopen("output.txt", "w", stdout);
#else
std::cin.tie(nullptr)->sync_with_stdio(false);
#endif
int n;
std::cin >> n;
std::vector a(n, std::vector<Mint>(n)), c(n, std::vector<Mint>(n));
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
std::cin >> a[i][j];
}
}
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
std::cin >> c[i][j];
}
}
std::mt19937 rng(std::chrono::steady_clock::now().time_since_epoch().count());
std::vector<int> r(n);
std::iota(r.begin(), r.end(), 0);
std::shuffle(r.begin(), r.end(), rng);
r.resize(std::min(n, 20));
std::vector<int> row, col;
for (int i = 0; i < n && (int)row.size() < 12; ++i) {
for (int j : r) {
Mint res = 0;
for (int k = 0; k < n; ++k) {
res += c[i][k] * a[k][j];
}
if (res != (i == j)) {
row.push_back(i);
break;
}
}
}
for (int i = 0; i < n && (int)col.size() < 12; ++i) {
for (int j : r) {
Mint res = 0;
for (int k = 0; k < n; ++k) {
res += a[i][k] * c[k][i];
}
if (res != (i == j)) {
col.push_back(i);
break;
}
}
}
const int m = (int)row.size() * (int)col.size();
std::vector val(n, std::vector(n, Row(m + 1)));
for (int i = 0; i < n; ++i) {
for (int j = 0; j < n; ++j) {
val[i][j].back() = c[i][j];
}
}
for (int i = 0; i < (int)row.size(); ++i) {
for (int j = 0; j < (int)col.size(); ++j) {
val[row[i]][col[j]].back() = 0;
val[row[i]][col[j]][(int)col.size() * i + j] = 1;
}
}
std::vector<Row> eq;
for (int i : col) {
for (int j = 0; j < (int)r.size(); ++j) {
Row res(m + 1);
for (int k = 0; k < n; ++k) {
res += a[r[j]][k] * val[k][i];
}
res.back() = (int)(r[j] == i) - res.back();
eq.push_back(res);
}
}
std::vector<Mint> sol = gauss(eq);
std::vector<std::pair<std::pair<int, int>, Mint>> ans;
for (int i = 0; i < (int)row.size(); ++i) {
for (int j = 0; j < (int)col.size(); ++j) {
Mint v = sol[(int)col.size() * i + j];
if (c[row[i]][col[j]] != v) {
ans.emplace_back(std::pair{row[i], col[j]}, v);
}
}
}
std::cout << (int)ans.size() << '\n';
for (auto [aa, b] : ans) {
std::cout << aa.first + 1 << ' ' << aa.second + 1 << ' ' << b << '\n';
}
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 0
Runtime Error
input:
1 953176428 107682094