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

#include <algorithm>
#include <iostream>
#include <sstream>
using namespace std;

int p;
string exp;
int index;
bool error;

int inverse(int a, int p);

int equation();
int factor();
int term();

int inverse(int x, int p) {
  int t = p - 2;
  int r = 1;
  while (t) {
    if (t & 1)
      r = r * x % p;
    x = x * x % p;
    t >>= 1;
  }
  return r;
}

int equation() {
  int res = factor();
  while (exp[index] == '+' || exp[index] == '-') {
    char op = exp[index++];
    int right = factor();
    if (op == '+')
      res = (res + right) % p;
    if (op == '-')
      res = (res - right + p) % p;
  }
  return res;
}
int factor() {
  int res = term();
  while (exp[index] == '*' || exp[index] == '/') {
    char op = exp[index++];
    int right = term();
    if (op == '*')
      res = res * right % p;
    if (op == '/') {
      if (right == 0)
        error = true;
      else
        res = res * inverse(right, p) % p;
    }
  }
  return res;
}
int term() {
  int res = 0;
  if (exp[index] == '(') {
    index++;
    res = equation();
    index++;
  } else {
    while (isdigit(exp[index]))
      res = res * 10 + exp[index++] - '0';
    res %= p;
  }
  return res;
}

int main() {
  string s;
  while (cin >> p, p != 0) {
    cin.ignore();
    getline(cin, s);
    s.erase(remove(s.begin(), s.end(), ' '), s.end());
    exp = s.c_str();
    // int main()
    // {
    //     while(cin>>p, p) {
    //         getline(cin, exp);
    //         while(exp.find(" ",0)!=string::npos) exp.erase(exp.find(" ",0),
    //         1); exp.erase(0, 1);

    index = 0;
    error = false;
    int ans = equation();
    if (error)
      cout << "NG" << endl;
    else
      cout << exp << " = " << ans << " (mod " << p << ")" << endl;
  }
}

Error: TLE

Fixed submission:

#include <iostream>
#include <sstream>
using namespace std;

long long p;
string exp;
long long index;
bool error;

long long inverse(long long a, long long p);

long long equation();
long long factor();
long long term();

long long inverse(long long x, long long p) {
  long long t = p - 2;
  long long r = 1;
  while (t) {
    if (t & 1)
      r = r * x % p;
    x = x * x % p;
    t >>= 1;
  }
  return r;
}

long long equation() {
  long long res = factor();
  while (exp[index] == '+' || exp[index] == '-') {
    char op = exp[index++];
    long long right = factor();
    if (op == '+')
      res = (res + right) % p;
    if (op == '-')
      res = (res - right + p) % p;
  }
  return res;
}
long long factor() {
  long long res = term();
  while (exp[index] == '*' || exp[index] == '/') {
    char op = exp[index++];
    long long right = term();
    if (op == '*')
      res = res * right % p;
    if (op == '/') {
      if (right == 0)
        error = true;
      else
        res = res * inverse(right, p) % p;
    }
  }
  return res;
}
long long term() {
  long long res = 0;
  if (exp[index] == '(') {
    index++;
    res = equation();
    index++;
  } else {
    while (isdigit(exp[index]))
      res = res * 10 + exp[index++] - '0';
    res %= p;
  }
  return res;
}

int main() {
  while (cin >> p, p) {
    getline(cin, exp);
    while (exp.find(" ", 0) != string::npos)
      exp.erase(exp.find(" ", 0), 1);
    exp.erase(0, 1);

    index = 0;
    error = false;
    long long ans = equation();
    if (error)
      cout << "NG" << endl;
    else
      cout << exp << " = " << ans << " (mod " << p << ")" << endl;
  }
}