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

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define UNIQUE(v) v.erase(unique(all(v)), v.end());
#define ZIP(v) sort(all(v)), UNIQUE(v)
#define ADD(a, b) a = (a + b) % mod
#define SUB(a, b) a = (a + mod - b) % mod
#define MUL(a, b) a = (a * b) % mod
#define repi(i, m, n) for (int i = m; i < n; i++)
#define drep(i, n, m) for (int i = n; i >= m; i--)
#define rep(i, n) repi(i, 0, n)
#define rrep(i, n) repi(i, 1, n + 1)
#define chmin(x, y) x = min(x, y)
#define chmax(x, y) x = max(x, y)
#define all(v) v.begin(), v.end()
#define rall(v) v.rbegin(), v.rend()
#define dmp(x, y) make_pair(x, y)
#define pb(x) push_back(x)
#define fi first
#define se second
typedef pair<int, int> P;
typedef pair<int, P> PP;
typedef pair<P, int> Pi;
typedef vector<int> vi;
typedef deque<int> dq;
const int inf = 1e9 + 7;
const int INF = 1e18 + 7;

int mod = -1;
int inv[50000];
int Pow(int x, int n) {
  if (n < 0)
    n += mod - 1;
  int ans = 1;
  while (n > 0) {
    if (n & 1)
      ans = (ans * x) % mod;
    x = (x * x) % mod;
    n >>= 1;
  }
  return ans;
}

string erase_space(string str) {
  int n = str.size();
  string ans = "";
  rep(i, n) {
    if (str[i] == ' ')
      continue;
    ans += str[i];
  }
  return ans;
}

int flag;
class Arithmetic {
public:
  string str;
  int n;
  void init(string s) {
    str = s;
    n = str.size();
  }
  int add(int a, int b) { return (mod + a + b % mod) % mod; }
  int mul(int a, int b) { return (a * b) % mod; }
  int div(int a, int b) {
    if (b == 0) {
      flag = 0;
      return 0;
    }
    return mul(a, inv[b]);
  }

  P get_num(int p) {
    int ans = 0, q = -1, f = 0;
    if (str[p] == '(')
      return solve(p + 1, 0);
    if (str[p] == '-') {
      f = 1;
      p++;
    }
    if (str[p] == '(') {
      P pi = solve(p + 1, 0);
      return P(-pi.fi, pi.se);
    }
    repi(i, p, n) {
      if (!isdigit(str[i]))
        break;
      ans = ans * 10 + (str[i] - '0');
      q = i;
    }
    if (f)
      return P(-ans, q);
    return P(ans, q);
  }

  P solve(int pp = 0, int f = 0) {
    P pi = get_num(pp);
    int ans = pi.fi, p = pi.se + 1;
    repi(i, p, n) {
      if (f and str[i] == ')')
        return P(ans, i - 1);
      if (str[i] == ')')
        return P(ans, i);
      if (str[i] == '*' or str[i] == '/') {
        pi = get_num(i + 1);
        if (str[i] == '*')
          ans = mul(ans, pi.fi);
        if (str[i] == '/')
          ans = div(ans, pi.fi);
        // if(f and str[pi.se+1] == ')')return P(ans, pi.se);
      }
      if (str[i] == '+' or str[i] == '-') {
        if (f)
          return P(ans, i - 1);
        if (str[i] == '+')
          pi = solve(i + 1, 1);
        if (str[i] == '-')
          pi = solve(i, 1);
        ans = add(ans, pi.fi);
      }
      i = pi.se;
    }
    return P(ans, n - 1);
  }
};

signed main() {
  Arithmetic A;
  /*mod = 17;
  string str = "1+3*(2+3/5*2)+7";
  //string str = "(2+3/5*2)";
  A.init(str);
  //printf("%lld\\n", Pow(5, -1));
  printf("%lld\\n", A.solve().fi);*/
  while (1) {
    string str;
    getline(cin, str);
    if (str == "0:")
      break;
    int idx = 0;
    rep(i, str.size()) {
      if (str[i] == ':') {
        idx = i;
        break;
      }
    }
    mod = atoll(str.substr(0, idx).c_str());
    str = erase_space(str.substr(idx + 1, str.size() - idx - 1));
    // rep(i,mod)inv[i] = Pow(i, -1);
    inv[1] = 1;
    for (int i = 2; i < mod; i++)
      inv[i] = mod - mod / i * inv[mod % i] % mod;
    flag = 1;
    A.init(str);
    P p = A.solve();
    if (flag == 0)
      cout << "NG" << endl;
    else {
      cout << str << " = " << p.fi;
      printf(" (mod %lld)\\n", mod);
    }
  }
  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define UNIQUE(v) v.erase(unique(all(v)), v.end());
#define ZIP(v) sort(all(v)), UNIQUE(v)
#define ADD(a, b) a = (a + b) % mod
#define SUB(a, b) a = (a + mod - b) % mod
#define MUL(a, b) a = (a * b) % mod
#define repi(i, m, n) for (int i = m; i < n; i++)
#define drep(i, n, m) for (int i = n; i >= m; i--)
#define rep(i, n) repi(i, 0, n)
#define rrep(i, n) repi(i, 1, n + 1)
#define chmin(x, y) x = min(x, y)
#define chmax(x, y) x = max(x, y)
#define all(v) v.begin(), v.end()
#define rall(v) v.rbegin(), v.rend()
#define dmp(x, y) make_pair(x, y)
#define pb(x) push_back(x)
#define fi first
#define se second
typedef pair<int, int> P;
typedef pair<int, P> PP;
typedef pair<P, int> Pi;
typedef vector<int> vi;
typedef deque<int> dq;
const int inf = 1e9 + 7;
const int INF = 1e18 + 7;

int mod = -1;
int inv[50000];
int Pow(int x, int n) {
  if (n < 0)
    n += mod - 1;
  int ans = 1;
  while (n > 0) {
    if (n & 1)
      ans = (ans * x) % mod;
    x = (x * x) % mod;
    n >>= 1;
  }
  return ans;
}

string erase_space(string str) {
  int n = str.size();
  string ans = "";
  rep(i, n) {
    if (str[i] == ' ')
      continue;
    ans += str[i];
  }
  return ans;
}

int flag;
class Arithmetic {
public:
  string str;
  int n;
  void init(string s) {
    str = s;
    n = str.size();
  }
  int add(int a, int b) { return (mod + a + b % mod) % mod; }
  int mul(int a, int b) { return (a * b) % mod; }
  int div(int a, int b) {
    if (b == 0) {
      flag = 0;
      return 0;
    }
    return mul(a, inv[b]);
  }

  P get_num(int p) {
    int ans = 0, q = -1, f = 0;
    if (str[p] == '(')
      return solve(p + 1, 0);
    if (str[p] == '-') {
      f = 1;
      p++;
    }
    if (str[p] == '(') {
      P pi = solve(p + 1, 0);
      return P(-pi.fi, pi.se);
    }
    repi(i, p, n) {
      if (!isdigit(str[i]))
        break;
      ans = ans * 10 + (str[i] - '0');
      q = i;
    }
    if (f)
      return P(-ans, q);
    return P(ans, q);
  }

  P solve(int pp = 0, int f = 0) {
    P pi = get_num(pp);
    int ans = pi.fi, p = pi.se + 1;
    repi(i, p, n) {
      if (f and str[i] == ')')
        return P(ans, i - 1);
      if (str[i] == ')')
        return P(ans, i);
      if (str[i] == '*' or str[i] == '/') {
        pi = get_num(i + 1);
        if (str[i] == '*')
          ans = mul(ans, pi.fi);
        if (str[i] == '/')
          ans = div(ans, pi.fi);
        // if(f and str[pi.se+1] == ')')return P(ans, pi.se);
      }
      if (str[i] == '+' or str[i] == '-') {
        if (f)
          return P(ans, i - 1);
        if (str[i] == '+')
          pi = solve(i + 1, 1);
        if (str[i] == '-')
          pi = solve(i, 1);
        ans = add(ans, pi.fi);
      }
      i = pi.se;
    }
    return P(ans, n - 1);
  }
};

signed main() {
  Arithmetic A;
  /*mod = 17;
  string str = "1+3*(2+3/5*2)+7";
  //string str = "(2+3/5*2)";
  A.init(str);
  //printf("%lld\\n", Pow(5, -1));
  printf("%lld\\n", A.solve().fi);*/
  while (1) {
    string str;
    getline(cin, str);
    if (str == "0:")
      break;
    int idx = 0;
    rep(i, str.size()) {
      if (str[i] == ':') {
        idx = i;
        break;
      }
    }
    mod = atoll(str.substr(0, idx).c_str());
    str = erase_space(str.substr(idx + 1, str.size() - idx - 1));
    rep(i, mod) inv[i] = Pow(i, -1);
    flag = 1;
    A.init(str);
    P p = A.solve();
    if (flag == 0)
      cout << "NG" << endl;
    else {
      cout << str << " = " << p.fi;
      printf(" (mod %lld)\\n", mod);
    }
  }
  return 0;
}