QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#317996#7612. Matrix Inversenhuang685RE 0ms0kbC++207.3kb2024-01-30 10:03:522024-01-30 10:03:53

Judging History

你现在查看的是最新测评结果

  • [2024-01-30 10:03:53]
  • 评测
  • 测评结果:RE
  • 用时:0ms
  • 内存:0kb
  • [2024-01-30 10:03:52]
  • 提交

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

output:


result: