Problem p01763 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <bits/stdc++.h>
#define int long long
#define r(i, n) for (int i = 0; i < n; i++)
using namespace std;

typedef long long ll;
struct NT {
  ll m; // mod
  vector<bool> ismrime;
  vector<ll> euler;
  vector<ll> fact;

  NT(ll MOD) {
    m = MOD;
    fact.resize(500005);
    fact[0] = 1;
    for (ll i = 1; i < 500005; i++) {
      fact[i] = (fact[i - 1] * i) % MOD;
    }
  }

  void eratos(int n) {
    ismrime.resize(n + 1);
    for (int i = 0; i <= n; i++)
      ismrime[i] = true;
    ismrime[0] = 0;
    ismrime[1] = 0;
    for (int i = 2; i <= n; i++) {
      if (ismrime[i]) {
        for (int j = i + i; j <= n; j += i)
          ismrime[j] = false;
      }
    }
  }

  // 因数分解 √N
  vector<int> mrime_decommosition(ll x) {
    vector<int> res;
    for (int i = 2; i * i <= x; i++) {
      while (x % i == 0) {
        x /= i;
        res.push_back(i);
      }
    }
    if (x != 1)
      res.push_back(x);
    return res;
  }

  // 約数列挙 √N
  vector<ll> divisor(ll x) {
    vector<ll> res;
    for (ll i = 1; i * i <= x; i++)
      if (x % i == 0) {
        res.push_back(i);
        if (i * i != x)
          res.push_back(x / i);
      }
    sort(res.begin(), res.end());
    return res;
  }

  // a*b>LONG_MAX ?
  bool overflow(ll a, ll b, ll LONGMAX) { return a > LONGMAX / b; }

  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 x, y;
    extgcd(a, m, x, y);
    return (m + x % m) % m;
  }
  ll mod_inverse_M(ll a, ll m) {
    ll x, y;
    extgcd(a, m, x, y);
    return (m + x % m) % m;
  }

  pair<ll, ll> linear_congruence(const vector<ll> &A, const vector<ll> &B,
                                 const vector<ll> &M) {
    ll x = 0, m = 1;
    for (int i = 0; i < A.size(); i++) {
      ll a = A[i] * m;
      ll b = B[i] - A[i] * x;
      ll d = __gcd(M[i], a);
      if (b % d != 0)
        return make_pair(0, -1);
      ll t = b / d * mod_inverse_M(a / d, M[i] / d) % (M[i] / d);
      x = x + m * t;
      m *= M[i] / d;
    }
    return make_pair(x % m, m);
  }

  // オイラー関数√N
  ll euler_mhi(ll n) {
    ll res = n;
    for (ll i = 2; i * i <= n; i++) {
      if (n % i == 0) {
        res = res / i * (i - 1);
        for (; n % i == 0; n /= i)
          ;
      }
    }
    if (n != 1)
      res = res / n * (n - 1);
    return res;
  }

  void make_euler_table(int n) {
    euler.resize(n + 1);
    for (int i = 0; i < n; i++)
      euler[i] = i;
    for (int i = 2; i < n; i++) {
      if (euler[i] == i) {
        for (int j = i; j < n; j += i) {
          euler[j] = euler[j] / i * (i - 1);
        }
      }
    }
  }

  // n! と nCr
  // mはmod
  ll mod_fact(ll n, ll &e) {
    e = 0;
    if (n == 0)
      return 1;

    int res = mod_fact(n / m, e);
    e += n / m;

    if (n / m % 2 != 0)
      return res * (m - fact[n % m]) % m;
    return res * fact[n % m] % m;
  }

  ll combination(ll n, ll k) {
    if (n == k || k == 0)
      return 1;
    if (n < 0 || k < 0 || n < k)
      return 0;
    ll e1, e2, e3;
    ll a1 = mod_fact(n, e1);
    ll a2 = mod_fact(k, e2);
    ll a3 = mod_fact(n - k, e3);
    return a1 * mod_inverse(a2 * a3 % m) % m;
  }

  ll mod_mult(ll a, ll b, ll m) {
    ll res = 0;
    ll exm = a % m;
    while (b) {
      if (b & 1) {
        res += exm;
        if (res > m)
          res -= m;
      }
      exm <<= 1;
      if (exm > m)
        exm -= m;
      b >>= 1;
    }
    return res;
  }

  ll mod_exm(ll a, ll b, ll m) {
    ll res = 1;
    ll exm = a % m;
    while (b) {
      if (b & 1)
        res = mod_mult(res, exm, m);
      exm = mod_mult(exm, exm, m);
      b >>= 1;
    }
    return res;
  }

  // 確率的高速素数判定　
  bool miller_rabin(ll n, ll times = 10) {
    if (n < 2)
      return false;
    if (n == 2)
      return true;
    if (!(n & 1))
      return false;
    ll q = n - 1;
    int k = 0;
    while (q % 2 == 0) {
      k++;
      q >>= 1;
    }
    for (int i = 0; i < times; i++) {
      ll a = rand() % (n - 1) + 1;
      ll x = mod_exm(a, q, n);
      if (x == 1)
        continue;
      bool found = false;
      for (int j = 0; j < k; j++) {
        if (x == n - 1) {
          found = true;
          break;
        }
        x = mod_mult(x, x, n);
      }
      if (found)
        continue;
      return false;
    }
    return true;
  }

  ll pollard_rho(ll n, int c) {
    ll x = 2;
    ll y = 2;
    ll d = 1;
    while (d == 1) {
      x = mod_mult(x, x, n) + c;
      y = mod_mult(y, y, n) + c;
      y = mod_mult(y, y, n) + c;
      d = __gcd((x - y >= 0 ? x - y : y - x), n);
    }
    if (d == n)
      return pollard_rho(n, c + 1);
    return d;
  }
};

int n, m[11], d, M;
signed main() {
  NT N(1e9 + 7);
  cin >> n >> M >> d;
  r(i, M) cin >> m[i];
  r(i, d) {
    vector<int> A, B, C;
    r(j, M) {
      int x;
      cin >> x;
      if (x != -1) {
        A.push_back(1);
        B.push_back(x);
        C.push_back(m[j]);
      }
    }
    pair<int, int> p = N.linear_congruence(A, B, C);
    if (p.second < 0) {
      cout << -1 << endl;
      return 0;
    }
    int x = p.first;
    /*int l=0,r=1e9;

    while(l<r){
            int mid=(l+r)/2;
            if(x+mid*p.second>=n)r=mid;
            else l=mid+1;
    }
    if(x+(l+2)*p.second<=n)n=x+(l+2)*p.second;
    else if(x+(l+1)*p.second<=n)n=x+(l+1)*p.second;
    else if(x+(l)*p.second<=n)n=x+(l)*p.second;
    else if(x+(l-1)*p.second<=n&&x+(l-1)*p.second>=0)n=x+(l-1)*p.second;
    else n=x+(l-2)*p.second;*/
    n = (n - x) / p.second;
    n *= p.second;
    n += x;
  }
  cout << n << endl;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> P;

int cal(int n, P p) {
  while (n % p.first != p.second && n >= 0)
    n--;
  return n;
}

int main() {
  int n, m, d, a[10];
  cin >> n >> m >> d;
  for (int i = 0; i < m; i++) {
    cin >> a[i];
  }
  P r[100][10];
  for (int i = 0; i < d; i++) {
    for (int j = 0; j < m; j++) {
      cin >> r[i][j].second;
      r[i][j].first = a[j];
    }
    sort(r[i], r[i] + m);
    reverse(r[i], r[i] + m);
    vector<int> v;
    for (int j = 0; j < m; j++) {
      if (r[i][j].second == -1)
        continue;
      if (j) {
        vector<int> nv;
        for (int k = 0; k < (int)v.size(); k++) {
          if (v[k] % r[i][j].first == r[i][j].second)
            nv.push_back(v[k]);
        }
        v = nv;
      } else {
        int u = 5e6;
        int p = cal(n, r[i][j]);
        while ((int)v.size() < u && p >= 0) {
          v.push_back(p);
          p -= r[i][j].first;
        }
      }
    }
    if (v.size())
      n = v[0];
    else if (r[i][0].second != -1)
      n = -1;
  }
  cout << n << endl;
  return 0;
}