Problem p01763 (C++) — buggy submission, verdict: Runtime Error

#include <bits/stdc++.h>
#define rep(i, n) for (ll i = 0; i < (ll)(n); i++)
#define all(a) ((a).begin(), (a).end())
using namespace std;
typedef long long ll;
typedef vector<ll> vi;
typedef pair<ll, ll> pii;

ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }

ll extgcd(ll a, ll b, ll &x, ll &y) {
  ll d = a;
  if (b != 0) {
    d = extgcd(b, a % b, y, x);
    y -= (a / b) * x;
  } else {
    x = 1;
    y = 0;
  }
  return d;
}

ll mod_inverse(ll a, ll m) {
  ll x, y;
  extgcd(a, m, x, y);
  return (m + x % m) % m;
}

pii linear_congruence(const vi &A, const vi &B, const vi &M) {
  ll x = 0, m = 1;
  rep(i, A.size()) {
    ll a = A[i] * m, b = B[i] - A[i] * x, d = gcd(M[i], a);
    if (b % d != 0)
      return make_pair(0, -1);
    ll t = b / d * mod_inverse(a / d, M[i] / d) % (M[i] / d);
    x = x + m * t;
    m *= M[i] / d;
  }
  return make_pair((x % m + m) % m, m);
}

int main() {
  ll n, m, d;
  cin >> n >> m >> d;
  vi a(m);
  rep(i, m) cin >> a[i];

  rep(i, d) {
    vi r, aa, e;
    rep(j, m) {
      ll tmp;
      cin >> tmp;
      if (tmp < 0)
        continue;
      r.push_back(tmp);
      aa.push_back(a[j]);
      e.push_back(1);
    }
    if (r.size() == 0)
      continue;

    pii ans = linear_congruence(e, r, aa);
    ll b = ans.first, mod = ans.second;
    if (mod < 0) {
      cout << -1 << endl;
      return 0;
    }

    ll tmp = (n / mod + 100) * mod + b;
    while (tmp < n)
      tmp += mod;
    while (n < tmp)
      tmp -= mod;
    if (tmp < 0) {
      cout << -1 << endl;
      return 0;
    }
    n = tmp;
  }

  cout << n << endl;
}

Error: 0

Fixed submission:

#include <bits/stdc++.h>
#define rep(i, n) for (ll i = 0; i < (ll)(n); i++)
#define all(a) ((a).begin(), (a).end())
using namespace std;
typedef long long ll;
typedef vector<ll> vi;
typedef pair<ll, ll> pii;

ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }

ll extgcd(ll a, ll b, ll &x, ll &y) {
  ll d = a;
  if (b != 0) {
    d = extgcd(b, a % b, y, x);
    y -= (a / b) * x;
  } else {
    x = 1;
    y = 0;
  }
  return d;
}

ll mod_inverse(ll a, ll m) {
  ll x, y;
  extgcd(a, m, x, y);
  return (m + x % m) % m;
}

pii linear_congruence(const vi &A, const vi &B, const vi &M) {
  ll x = 0, m = 1;
  rep(i, A.size()) {
    ll a = A[i] * m, b = B[i] - A[i] * x, d = gcd(M[i], a);
    if (b % d != 0)
      return make_pair(0, -1);
    ll t = b / d * mod_inverse(a / d, M[i] / d) % (M[i] / d);
    x = x + m * t;
    m *= M[i] / d;
  }
  return make_pair((x % m + m) % m, m);
}

int main() {
  ll n, m, d;
  cin >> n >> m >> d;
  vi a(m);
  rep(i, m) cin >> a[i];

  rep(i, d) {
    vi r, aa, e;
    rep(j, m) {
      ll tmp;
      cin >> tmp;
      if (tmp < 0)
        continue;
      r.push_back(tmp);
      aa.push_back(a[j]);
      e.push_back(1);
    }
    assert(r.size() == m || r.size() == 0);
    if (r.size() == 0)
      continue;

    pii ans = linear_congruence(e, r, a);
    ll b = ans.first, mod = ans.second;
    if (mod < 0) {
      cout << -1 << endl;
      return 0;
    }

    ll tmp = (n / mod + 100) * mod + b;
    while (tmp < n)
      tmp += mod;
    while (n < tmp)
      tmp -= mod;
    if (tmp < 0) {
      cout << -1 << endl;
      return 0;
    }
    n = tmp;
  }

  cout << n << endl;
}