Problem p01087 (C++) — buggy submission, verdict: Runtime Error

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

constexpr int MUL = -202020;
constexpr int ADD = -292929;
using ex = pair<int, long>;
constexpr ex INVALID = ex(-1, -1);

int isOperatorChar(char c) {
  if (c == '+')
    return ADD;
  if (c == '*')
    return MUL;
  return 0;
}

bool isOperator(int o) { return o == ADD || o == MUL; }

bool isNumber(char c) { return c >= '0' && c <= '9'; }

ex getOrderExp(string s) {
  int cnt = 0;
  for (auto c : s) {
    if (c == '.')
      cnt++;
    else if (isOperatorChar(c)) {
      return ex(cnt + 1, isOperatorChar(c));
    } else {
      return ex(cnt, c - '0');
    };
  }
  return ex(-1, -1);
}

void debugExp(vector<ex> &v) {
  for (auto &w : v) {
    // cerr << "order: " << w.first << "\\t" << w.second << endl;
  }
}

int getLargestOrder(vector<ex> &v) {
  int ret = 0;
  for (auto &w : v) {
    ret = max(ret, w.first);
  }
  return ret;
}

void solve(int n) {
  vector<ex> v;
  for (int i = 0; i < n; i++) {
    string s;
    cin >> s;
    v.push_back(getOrderExp(s));
  }

  while (1) {
    int order = getLargestOrder(v);
    // cerr << "current order: " << order << endl;
    debugExp(v);
    if (order == 0)
      break;
    vector<ex> lower;
    vector<ex> higher;
    for (auto &w : v) {
      if (w.first != order || isOperator(w.second)) {
        if (higher.size()) {
          if (higher.front().second == ADD) {
            long ret = 0;
            for (int i = 1; i < higher.size(); i++) {
              ret += higher[i].second;
            }
            lower.push_back(ex(order - 1, ret));
            // cerr << "reducing: ret=" << ret << endl;
          } else if (higher.front().second == MUL) {
            long ret = 1;
            for (int i = 1; i < higher.size(); i++) {
              ret *= higher[i].second;
            }
            lower.push_back(ex(order - 1, ret));
            // cerr << "reducing: ret=" << ret << endl;
          }
          higher.clear();
        }
        if (w.first != order) {
          lower.push_back(w);
        } else {
          higher.push_back(w);
        }
      } else {
        higher.push_back(w);
      }
    }
    if (higher.size()) {
      if (higher.front().second == ADD) {
        long ret = 0;
        for (int i = 1; i < higher.size(); i++) {
          ret += higher[i].second;
        }
        lower.push_back(ex(order - 1, ret));
        // cerr << "reducing: ret=" << ret << endl;
      } else if (higher.front().second == MUL) {
        long ret = 1;
        for (int i = 1; i < higher.size(); i++) {
          ret *= higher[i].second;
        }
        lower.push_back(ex(order - 1, ret));
        // cerr << "reducing: ret=" << ret << endl;
      }
    }
    v = vector<ex>(lower);
  }
  cout << v.front().second << endl;
}

int main() {
  long n;
  while (1) {
    cin >> n;
    if (n) {
      solve(n);
    } else {
      return 0;
    }
  }
}


Error: 0
current order: 0
order: 0	9
current order: 1
order: 1	-292929
order: 1	1
order: 1	2
order: 1	3
reducing: ret=6
current order: 0
order: 0	6
current order: 4
order: 1	-292929
order: 1	0
order: 2	-292929
order: 3	-202020
order: 3	1
order: 4	-202020
order: 4	1
order: 4	2
order: 2	0
reducing: ret=2
current order: 3
order: 1	-292929
order: 1	0
order: 2	-292929
order: 3	-202020
order: 3	1
order: 3	2
order: 2	0
reducing: ret=2
current order: 2
order: 1	-292929
order: 1	0
order: 2	-292929
order: 2	2
order: 2	0
reducing: ret=2
current order: 1
order: 1	-292929
order: 1	0
order: 1	2
reducing: ret=2
current order: 0
order: 0	2
current order: 3
order: 1	-292929
order: 2	-292929
order: 2	6
order: 2	2
order: 2	-292929
order: 2	1
order: 3	-202020
order: 3	7
order: 3	6
order: 1	3
reducing: ret=42
current order: 2
order: 1	-292929
order: 2	-292929
order: 2	6
order: 2	2
order: 2	-292929
order: 2	1
order: 2	42
order: 1	3
reducing: ret=8
reducing: ret=43
current order: 1
order: 1	-292929
order: 1	8
order: 1	43
order: 1	3
reducing: ret=54
current order: 0
order: 0	54


Fixed submission:

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

constexpr int MUL = -202020;
constexpr int ADD = -292929;
using ex = pair<int, long>;
constexpr ex INVALID = ex(-1, -1);

int isOperatorChar(char c) {
  if (c == '+')
    return ADD;
  if (c == '*')
    return MUL;
  return 0;
}

bool isOperator(int o) { return o == ADD || o == MUL; }

bool isNumber(char c) { return c >= '0' && c <= '9'; }

ex getOrderExp(string s) {
  int cnt = 0;
  for (auto c : s) {
    if (c == '.')
      cnt++;
    else if (isOperatorChar(c)) {
      return ex(cnt + 1, isOperatorChar(c));
    } else {
      return ex(cnt, c - '0');
    };
  }
  return ex(-1, -1);
}

void debugExp(vector<ex> &v) {
  for (auto &w : v) {
    cerr << "order: " << w.first << "\\t" << w.second << endl;
  }
}

int getLargestOrder(vector<ex> &v) {
  int ret = 0;
  for (auto &w : v) {
    ret = max(ret, w.first);
  }
  return ret;
}

void solve(int n) {
  vector<ex> v;
  for (int i = 0; i < n; i++) {
    string s;
    cin >> s;
    v.push_back(getOrderExp(s));
  }

  while (1) {
    int order = getLargestOrder(v);
    cerr << "current order: " << order << endl;
    debugExp(v);
    if (order == 0)
      break;
    vector<ex> lower;
    vector<ex> higher;
    for (auto &w : v) {
      if (w.first != order || isOperator(w.second)) {
        if (higher.size()) {
          if (higher.front().second == ADD) {
            long ret = 0;
            for (int i = 1; i < higher.size(); i++) {
              ret += higher[i].second;
            }
            lower.push_back(ex(order - 1, ret));
            cerr << "reducing: ret=" << ret << endl;
          } else if (higher.front().second == MUL) {
            long ret = 1;
            for (int i = 1; i < higher.size(); i++) {
              ret *= higher[i].second;
            }
            lower.push_back(ex(order - 1, ret));
            cerr << "reducing: ret=" << ret << endl;
          }
          higher.clear();
        }
        if (w.first != order) {
          lower.push_back(w);
        } else {
          higher.push_back(w);
        }
      } else {
        higher.push_back(w);
      }
    }
    if (higher.size()) {
      if (higher.front().second == ADD) {
        long ret = 0;
        for (int i = 1; i < higher.size(); i++) {
          ret += higher[i].second;
        }
        lower.push_back(ex(order - 1, ret));
        cerr << "reducing: ret=" << ret << endl;
      } else if (higher.front().second == MUL) {
        long ret = 1;
        for (int i = 1; i < higher.size(); i++) {
          ret *= higher[i].second;
        }
        lower.push_back(ex(order - 1, ret));
        cerr << "reducing: ret=" << ret << endl;
      }
    }
    v = vector<ex>(lower);
  }
  cout << v.front().second << endl;
}

int main() {
  long n;
  while (1) {
    cin >> n;
    if (n) {
      solve(n);
    } else {
      return 0;
    }
  }
}