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

#include <bits/stdc++.h>
using namespace std;
typedef __int128 Val;

const Val MOD = 1e18 + 9;
vector<Val> var;

void skip(string &s, int &p) {
  while (p < s.size() && s[p] == ' ')
    p++;
}

Val formula(string &s, int &p);

Val num(string &s, int &p) {
  Val res = 0.;
  while (p < s.size() && isdigit(s[p])) {
    res *= 10.;
    res += s[p] - '0';
    res %= MOD;
    p++;
  }
  skip(s, p);
  return res;
}

Val var_val(string &s, int &p) {
  Val res = var[s[p] - 'a'];
  p++;
  skip(s, p);
  return res;
}

Val get_val(string &s, int &p) {
  if (s[p] == '(') {
    p++;
    skip(s, p);
    Val res = formula(s, p);
    assert(s[p] == ')');
    p++;
    skip(s, p);
    res %= MOD;
    return res;
  }
  if (isalpha(s[p])) {
    return var_val(s, p);
  }
  if (isdigit(s[p])) {
    return num(s, p);
  }
  assert(0);
}

Val term2(string &s, int &p) {
  Val res = get_val(s, p);
  if (p < s.size() && s[p] == '^') {
    p++;
    skip(s, p);
    Val val = term2(s, p);
    Val a = res;
    res = 1;
    for (int i = 0; i < val; i++) {
      res *= a;
      res %= MOD;
    }
    return res;
  }
  return res;
}

Val term1(string &s, int &p) {
  Val res = term2(s, p);
  while (p < s.size() && s[p] != ')' && s[p] != '+' && s[p] != '-') {
    skip(s, p);
    assert(isalpha(s[p]) || isdigit(s[p]) || s[p] == '(');
    Val val = term2(s, p);
    res *= val;
    res %= MOD;
  }
  return res;
}

Val formula(string &s, int &p) {
  Val res = term1(s, p);
  while (p < s.size() && s[p] != ')') {
    char op = s[p];
    assert(op == '+' || op == '-');
    p++;
    skip(s, p);
    Val val = term1(s, p);
    if (op == '+')
      res += val;
    else
      res -= val;
    res %= MOD;
  }
  return res;
}

void solve(vector<string> &state) {
  random_device rnd;
  var.resize('z' - 'a' + 1);
  for (int i = 1; i < state.size(); i++) {
    bool isok = true;
    const int TIME = 1000;
    for (int j = 0; j < TIME; j++) {
      int p = 0;
      for (int i = 0; i <= 'z' - 'a'; i++) {
        var[i] = rnd() % TIME;
      }
      Val cor = formula(state[0], p);
      cor %= MOD;
      cor += MOD;
      cor %= MOD;
      p = 0;
      Val ans = formula(state[i], p);
      ans %= MOD;
      ans += MOD;
      ans %= MOD;
      isok &= (cor == ans);
    }
    cout << (isok ? "yes" : "no") << endl;
  }
  cout << "." << endl;
  return;
}

int main() {
  while (true) {
    vector<string> state;
    while (true) {
      string buf;
      getline(cin, buf);
      if (buf == ".")
        break;
      state.push_back(buf);
    }
    if (state.size() == 0)
      break;
    solve(state);
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

const double EPS = 1e-8;
vector<double> var;

void skip(string &s, int &p) {
  while (p < s.size() && s[p] == ' ')
    p++;
}
double formula(string &s, int &p);

double num(string &s, int &p) {
  double res = 0;
  while (p < s.size() && isdigit(s[p])) {
    res *= 10;
    res += s[p] - '0';
    p++;
  }
  skip(s, p);
  return res;
}

double var_val(string &s, int &p) {
  double res = var[s[p] - 'a'];
  p++;
  skip(s, p);
  return res;
}

double get_val(string &s, int &p) {
  if (s[p] == '(') {
    p++;
    skip(s, p);
    double res = formula(s, p);
    assert(s[p] == ')');
    p++;
    skip(s, p);
    return res;
  }
  if (isalpha(s[p])) {
    return var_val(s, p);
  }
  if (isdigit(s[p])) {
    return num(s, p);
  }
  assert(0);
}

double term2(string &s, int &p) {
  double res = get_val(s, p);
  if (p < s.size() && s[p] == '^') {
    p++;
    skip(s, p);
    return pow(res, term2(s, p));
  }
  return res;
}

double term1(string &s, int &p) {
  double res = term2(s, p);
  while (p < s.size() && s[p] != ')' && s[p] != '+' && s[p] != '-') {
    assert(isalpha(s[p]) || isdigit(s[p]) || s[p] == '(');
    double val = term2(s, p);
    res *= val;
  }
  return res;
}

double formula(string &s, int &p) {
  double res = term1(s, p);
  while (p < s.size() && s[p] != ')') {
    char op = s[p];
    assert(op == '+' || op == '-');
    p++;
    skip(s, p);
    double val = term1(s, p);
    if (op == '+')
      res += val;
    else
      res -= val;
  }
  return res;
}

void solve(vector<string> &state) {
  random_device rnd;
  var.resize('z' - 'a' + 1);
  for (int i = 1; i < state.size(); i++) {
    bool isok = true;
    const int TIME = 10000;
    for (int j = 0; j < TIME; j++) {
      int p = 0;
      for (int i = 0; i <= 'z' - 'a'; i++) {
        var[i] = rnd();
      }
      double cor = formula(state[0], p);
      p = 0;
      double ans = formula(state[i], p);
      isok &= (abs(cor - ans) < EPS);
    }
    cout << (isok ? "yes" : "no") << endl;
  }
  return;
}

int main() {
  while (true) {
    vector<string> state;
    while (true) {
      string buf;
      getline(cin, buf);
      if (buf == ".")
        break;
      state.push_back(buf);
    }
    if (state.size() == 0)
      break;
    solve(state);
  }
  return 0;
}