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

#include <bits/stdc++.h>
using namespace std;
#define REP(i, n) for (int i = 0; i < (int)(n); ++i)
#define FOR(i, c)                                                              \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define ALL(c) (c).begin(), (c).end()
#define valid(y, x, h, w) (0 <= y && y < h && 0 <= x && x < w)
#define tpl(...) make_tuple(__VA_ARGS__)
const int INF = 0x3f3f3f3f;
const double EPS = 1e-8;
const double PI = acos(-1);
typedef long long ll;
typedef pair<int, int> pii;
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> bool chmin(T &a, const T &b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> ostream &operator<<(ostream &o, const vector<T> &t) {
  o << '[';
  FOR(i, t) {
    if (i != t.begin())
      o << ',';
    o << *i;
  }
  return o << ']';
}
template <class S, class T>
ostream &operator<<(ostream &o, const pair<S, T> &t) {
  return o << '(' << t.first << ',' << t.second << ')';
}
template <int N, class Tp> void output(ostream &, const Tp &) {}
template <int N, class Tp, class, class... Ts>
void output(ostream &o, const Tp &t) {
  if (N)
    o << ',';
  o << get<N>(t);
  output<N + 1, Tp, Ts...>(o, t);
}
template <class... Ts> ostream &operator<<(ostream &o, const tuple<Ts...> &t) {
  o << '(';
  output<0, tuple<Ts...>, Ts...>(o, t);
  return o << ')';
}
template <class T> void output(T t, char z = 10) {
  if (t < 0)
    t = -t, putchar(45);
  int c[20];
  int k = 0;
  while (t)
    c[k++] = t % 10, t /= 10;
  for (k || (c[k++] = 0); k;)
    putchar(c[--k] ^ 48);
  putchar(z);
}
template <class T> void outputs(T t) { output(t); }
template <class S, class... T> void outputs(S a, T... t) {
  output(a, 32);
  outputs(t...);
}
template <class T> void output(T *a, int n) {
  REP(i, n) output(a[i], i != n - 1 ? ',' : 10);
}
template <class T> void output(T *a, int n, int m) {
  REP(i, n) output(a[i], m);
}
template <class T> bool input(T &t) {
  int n = 1, c;
  for (t = 0; !isdigit(c = getchar()) && ~c && c - 45;)
    ;
  if (!~c)
    return 0;
  for (c - 45 && (n = 0, t = c ^ 48); isdigit(c = getchar());)
    t = 10 * t + c - 48;
  t = n ? -t : t;
  return 1;
}
template <class S, class... T> bool input(S &a, T &...t) {
  input(a);
  return input(t...);
}

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

ll mulmod(ll a, ll n, ll m) {
  ll res = 0;
  while (n >= 1) {
    if (n % 2 == 1)
      res = (res + a) % m;
    a = a * 2 % m;
    n >>= 1;
  }
  return res;
}

ll ChineseRemainderTheorem(const vector<ll> &B, const vector<ll> &M) {
  ll all = 1;
  FOR(it, M) all *= *it;
  ll res = 0;
  REP(i, B.size()) {
    ll x, y;
    extgcd(M[i], all / M[i], x, y);
    y = (y % all + all) % all;
    res = (res % all + mulmod(mulmod(B[i], y, all), (all / M[i]), all) % all +
           all) %
          all;
    // assert(res >= 0);
  }
  return res;
}
vector<int> factorize(ll n) { // O(√n)
  vector<int> res;
  for (ll i = 2; i * i <= n; ++i) {
    int r = 1;
    while (n % i == 0) {
      n /= i;
      r *= i;
    }
    if (r > 1) {
      res.push_back(r);
    }
  }
  if (n != 1)
    res.push_back(n);
  return res;
}

int a[10];
int x[100][10];

int main() {
  int n, m, d;
  while (input(n, m, d)) {
    vector<vector<int>> facts;
    REP(i, m) {
      input(a[i]);
      facts.push_back(factorize(a[i]));
    }
    REP(i, d) REP(j, m) input(x[i][j]);
    bool ng = 0;
    ll cur = n;
    REP(i, d) {
      map<int, int> mp;
      REP(j, m) {
        if (x[i][j] == -1)
          continue;
        FOR(it, facts[j]) {
          if (mp.count(*it) && mp[*it] != x[i][j] % *it)
            ng = 1;
          mp[*it] = x[i][j] % *it;
        }
      }
      FOR(it, mp) {
        FOR(jt, mp) {
          if (jt->first % it->first == 0 &&
              (it->second % it->first != jt->second % it->first)) {
            ng = 1;
          }
        }
      }
      if (ng)
        break;
      vector<ll> v1, v2;
      FOR(it, mp) {
        bool f = 0;
        FOR(jt, mp) {
          if (it->first < jt->first && jt->first % it->first == 0)
            f = 1;
        }
        if (!f) {
          v1.push_back(it->second);
          v2.push_back(it->first);
        }
      }
      ll res = ChineseRemainderTheorem(v1, v2);
      ll md = 1;
      FOR(it, v2) md *= *it;
      FOR(it, v2) {
        FOR(jt, v2) {
          if (*it != *jt)
            assert(__gcd(*it, *jt) == 1);
        }
      }
      REP(i, v1.size()) { assert(res % v2[i] == v1[i]); }

      // cout << v1 << endl;
      // cout << v2 << endl;
      // cout << res << " " << md << endl;
      // md*x + res <= cur
      // x <= (cur - res) / md
      if (res > cur) {
        ng = 1;
        break;
      }
      ll x = (cur - res) / md;
      cur = x * md + res;
      // cout << endl;
    }
    if (ng)
      cout << -1 << endl;
    else
      cout << cur << endl;
  }
}

Error: 0

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
#define REP(i, n) for (int i = 0; i < (int)(n); ++i)
#define FOR(i, c)                                                              \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define ALL(c) (c).begin(), (c).end()
#define valid(y, x, h, w) (0 <= y && y < h && 0 <= x && x < w)
#define tpl(...) make_tuple(__VA_ARGS__)
const int INF = 0x3f3f3f3f;
const double EPS = 1e-8;
const double PI = acos(-1);
typedef long long ll;
typedef pair<int, int> pii;
template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> bool chmin(T &a, const T &b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> ostream &operator<<(ostream &o, const vector<T> &t) {
  o << '[';
  FOR(i, t) {
    if (i != t.begin())
      o << ',';
    o << *i;
  }
  return o << ']';
}
template <class S, class T>
ostream &operator<<(ostream &o, const pair<S, T> &t) {
  return o << '(' << t.first << ',' << t.second << ')';
}
template <int N, class Tp> void output(ostream &, const Tp &) {}
template <int N, class Tp, class, class... Ts>
void output(ostream &o, const Tp &t) {
  if (N)
    o << ',';
  o << get<N>(t);
  output<N + 1, Tp, Ts...>(o, t);
}
template <class... Ts> ostream &operator<<(ostream &o, const tuple<Ts...> &t) {
  o << '(';
  output<0, tuple<Ts...>, Ts...>(o, t);
  return o << ')';
}
template <class T> void output(T t, char z = 10) {
  if (t < 0)
    t = -t, putchar(45);
  int c[20];
  int k = 0;
  while (t)
    c[k++] = t % 10, t /= 10;
  for (k || (c[k++] = 0); k;)
    putchar(c[--k] ^ 48);
  putchar(z);
}
template <class T> void outputs(T t) { output(t); }
template <class S, class... T> void outputs(S a, T... t) {
  output(a, 32);
  outputs(t...);
}
template <class T> void output(T *a, int n) {
  REP(i, n) output(a[i], i != n - 1 ? ',' : 10);
}
template <class T> void output(T *a, int n, int m) {
  REP(i, n) output(a[i], m);
}
template <class T> bool input(T &t) {
  int n = 1, c;
  for (t = 0; !isdigit(c = getchar()) && ~c && c - 45;)
    ;
  if (!~c)
    return 0;
  for (c - 45 && (n = 0, t = c ^ 48); isdigit(c = getchar());)
    t = 10 * t + c - 48;
  t = n ? -t : t;
  return 1;
}
template <class S, class... T> bool input(S &a, T &...t) {
  input(a);
  return input(t...);
}

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

ll ChineseRemainderTheorem(const vector<ll> &B, const vector<ll> &M) {
  ll all = 1;
  FOR(it, M) all *= *it;
  ll res = 0;
  REP(i, B.size()) {
    ll x, y;
    extgcd(M[i], all / M[i], x, y);
    y = (y % all + all) % all;
    res = (res % all + B[i] * y * (all / M[i]) % all + all) % all;
    // assert(res >= 0);
  }
  return res;
}
vector<int> factorize(ll n) { // O(√n)
  vector<int> res;
  for (ll i = 2; i * i <= n; ++i) {
    int r = 1;
    while (n % i == 0) {
      n /= i;
      r *= i;
    }
    if (r > 1) {
      res.push_back(r);
    }
  }
  if (n != 1)
    res.push_back(n);
  return res;
}

int a[10];
int x[100][10];

int main() {
  int n, m, d;
  while (input(n, m, d)) {
    vector<vector<int>> facts;
    REP(i, m) {
      input(a[i]);
      facts.push_back(factorize(a[i]));
    }
    REP(i, d) REP(j, m) input(x[i][j]);
    bool ng = 0;
    ll cur = n;
    REP(i, d) {
      map<int, int> mp;
      REP(j, m) {
        if (x[i][j] == -1)
          continue;
        FOR(it, facts[j]) {
          if (mp.count(*it) && mp[*it] != x[i][j] % *it)
            ng = 1;
          mp[*it] = x[i][j] % *it;
        }
      }
      FOR(it, mp) {
        FOR(jt, mp) {
          if (jt->first % it->first == 0 &&
              (it->second % it->first != jt->second % it->first)) {
            ng = 1;
          }
        }
      }
      if (ng)
        break;
      vector<ll> v1, v2;
      FOR(it, mp) {
        bool f = 0;
        FOR(jt, mp) {
          if (it->first < jt->first && jt->first % it->first == 0)
            f = 1;
        }
        if (!f) {
          v1.push_back(it->second);
          v2.push_back(it->first);
        }
      }
      ll res = ChineseRemainderTheorem(v1, v2);
      ll md = 1;
      FOR(it, v2) md *= *it;
      FOR(it, v2) {
        FOR(jt, v2) {
          if (*it != *jt)
            assert(__gcd(*it, *jt) == 1);
        }
      }
      REP(i, v1.size()) { assert(res % v2[i] == v1[i]); }

      // cout << v1 << endl;
      // cout << v2 << endl;
      // cout << res << " " << md << endl;
      // md*x + res <= cur
      // x <= (cur - res) / md
      if (res > cur) {
        ng = 1;
        break;
      }
      ll x = (cur - res) / md;
      cur = x * md + res;
      // cout << endl;
    }
    if (ng)
      cout << -1 << endl;
    else
      cout << cur << endl;
  }
}