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

#include <algorithm>
#include <cassert>
#include <cctype>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int, int> pii;

#define reps(i, f, n) for (int i = f; i < int(n); ++i)
#define rep(i, n) reps(i, 0, n)

int p;
string s;

int expr(int &t);

int inv(int n) {
  if (n == 0)
    throw 0;

  int r = 1;
  int t = n;
  for (int e = p - 2; e; e >>= 1) {
    if (e & 1)
      r = (r * t) % p;
    t = (t * t) % p;
  }
  return r;
}

int num(int &t) {
  if (s[t] == '(') {
    ++t;
    int v = expr(t);
    ++t;
    return v;
  } else {
    int v = 0;
    while (isdigit(s[t])) {
      v = v * 10 + s[t++] - '0';
    }
    return v;
  }
}

int term(int &t) {
  int a = num(t);
  while (s[t] == '*' || s[t] == '/') {
    char c = s[t++];
    int u = num(t);
    if (c == '/')
      u = inv(u);
    a = (a * u) % p;
  }
  return a;
}

int expr(int &t) {
  int a = term(t);
  while (s[t] == '+' || s[t] == '-') {
    char c = s[t++];
    int u = term(t);
    if (c == '-')
      u *= -1;
    a = (a + u + p) % p;
  }
  return a;
}

string func(string str) {
  p = stoi(str);

  stringstream sstr(str.substr(str.find(':') + 1));
  str = "";
  for (string t; sstr >> t;) {
    str += t;
  }

  try {
    int t = 0;
    s = str + '\\0';
    int v = expr(t);
    return str + " = " + to_string(v) + " (mod " + to_string(p) + ")";
  } catch (...) {
    return "NG";
  }
}

int main() {
  string str;
  while (getline(cin, str), str != "0:") {
    cout << func(str) << endl;
  }
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cctype>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int, int> pii;

#define reps(i, f, n) for (int i = f; i < int(n); ++i)
#define rep(i, n) reps(i, 0, n)

int p;
string s;

int expr(int &t);

int inv(int n) {
  if (n == 0)
    throw 0;

  int r = 1;
  rep(i, p - 2) r = (r * n) % p;
  return r;
}

int num(int &t) {
  if (s[t] == '(') {
    ++t;
    int v = expr(t);
    ++t;
    return v;
  } else {
    int v = 0;
    while (isdigit(s[t])) {
      v = v * 10 + s[t++] - '0';
    }
    return v;
  }
}

int term(int &t) {
  int a = num(t);
  while (s[t] == '*' || s[t] == '/') {
    char c = s[t++];
    int u = num(t);
    if (c == '/')
      u = inv(u);
    a = (a * u) % p;
  }
  return a;
}

int expr(int &t) {
  int a = term(t);
  while (s[t] == '+' || s[t] == '-') {
    char c = s[t++];
    int u = term(t);
    if (c == '-')
      u *= -1;
    a = (a + u + p) % p;
  }
  return a;
}

string func(string str) {
  p = stoi(str);

  stringstream sstr(str.substr(str.find(':') + 1));
  s = "";
  for (string t; sstr >> t;) {
    s += t;
  }
  s += '\\0';

  try {
    int t = 0;
    int v = expr(t);
    return s.substr(0, s.size() - 1) + " = " + to_string(v) + " (mod " +
           to_string(p) + ")";
  } catch (...) {
    return "NG";
  }
}

int main() {
  string str;
  while (getline(cin, str), str != "0:") {
    cout << func(str) << endl;
  }
}