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

#include <bits/stdc++.h>

#define _overload(_1, _2, _3, name, ...) name
#define _rep(i, n) _range(i, 0, n)
#define _range(i, a, b) for (int i = int(a); i < int(b); ++i)
#define rep(...) _overload(__VA_ARGS__, _range, _rep, )(__VA_ARGS__)

#define _rrep(i, n) _rrange(i, n, 0)
#define _rrange(i, a, b) for (int i = int(a) - 1; i >= int(b); --i)
#define rrep(...) _overload(__VA_ARGS__, _rrange, _rrep, )(__VA_ARGS__)

#define _all(arg) begin(arg), end(arg)
#define uniq(arg) sort(_all(arg)), (arg).erase(unique(_all(arg)), end(arg))
#define getidx(ary, key) lower_bound(_all(ary), key) - begin(ary)
#define clr(a, b) memset((a), (b), sizeof(a))
#define bit(n) (1LL << (n))
#define popcount(n) (__builtin_popcountll(n))

using namespace std;

template <class T> bool chmax(T &a, const T &b) {
  return (a < b) ? (a = b, 1) : 0;
}
template <class T> bool chmin(T &a, const T &b) {
  return (b < a) ? (a = b, 1) : 0;
}

using ll = long long;
using R = long double;
const R EPS = 1e-9L; // [-1000,1000]->EPS=1e-8 [-10000,10000]->EPS=1e-7
inline int sgn(const R &r) { return (r > EPS) - (r < -EPS); }
inline R sq(R x) { return sqrt(max(x, 0.0L)); }

const int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
const int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};

// Problem Specific Parameter:

const int deg = 11;
using P = array<int, deg>;
P primary(const string &, int &);
P factor(const string &, int &);
P term(const string &, int &);
P expression(const string &, int &);

int number(const string &s, int &cur) {
  int ret = s[cur++] - '0';
  while (isdigit(s[cur])) {
    ret = 10 * ret + s[cur++] - '0';
  }
  return ret;
}

P mul(P a, P b) {
  P ret;
  fill(begin(ret), end(ret), 0);

  rep(i, deg) rep(j, deg) {
    if (i + j >= deg)
      continue;
    ret[i + j] += a[i] * b[j];
  }
  return ret;
}

P primary(const string &s, int &cur) {
  P ret;
  fill(begin(ret), end(ret), 0);

  if (s[cur] == 'x') {
    cur++;
    ret[1] = 1;
  } else if (s[cur] == '(') {
    cur++;
    ret = expression(s, cur);
    cur++;
  } else if (isdigit(s[cur])) {
    ret[0] = number(s, cur);
  } else {
    assert(false);
  }

  return ret;
}

P factor(const string &s, int &cur) {
  P ret = primary(s, cur);
  if (s[cur] == '^') {
    cur++;
    int idx = number(s, cur);
    P tmp = ret;
    rep(loop, idx - 1) ret = mul(ret, tmp);
  }
  return ret;
}

P term(const string &s, int &cur) {
  P ret = factor(s, cur);
  while (s[cur] == 'x' or s[cur] == '(') {
    ret = mul(ret, factor(s, cur));
  }
  return ret;
}

P expression(const string &s, int &cur) {
  bool minus = false;
  if (s[cur] == '-') {
    cur++;
    minus = true;
  }

  P ret = term(s, cur);
  if (minus) {
    rep(i, deg) ret[i] *= -1;
  }

  while (s[cur] == '+' or s[cur] == '-') {
    char op = s[cur++];
    P tmp = term(s, cur);
    if (op == '+') {
      rep(i, deg) ret[i] = ret[i] + tmp[i];
    } else {
      rep(i, deg) ret[i] = ret[i] - tmp[i];
    }
  }

  return ret;
}

void output(P res) {

  bool start = false;

  int ng = -1;
  rrep(i, deg) if (ng == -1 and res[i] != 0) ng = i;

  if (res[ng] < 0) {
    rep(i, deg) res[i] *= -1;
  }

  rrep(i, deg) {
    if (res[i] == 0)
      continue;

    if (start) {
      if (res[i] > 0)
        cout << "+";
      else
        cout << "-";
    }

    if (i == 0 or abs(res[i]) != 1)
      cout << abs(res[i]);

    if (i >= 1) {
      cout << "x";
      if (i >= 2)
        cout << "^" << i;
    }

    start = true;
  }

  cout << endl;
}

P normalize(P p) {
  int g = 0;
  rep(i, deg) g = __gcd(g, p[i]);
  if (g == 0)
    return p;
  rep(i, deg) p[i] /= g;
  return p;
}

P gcd(P a, P b) {
  a = normalize(a);
  b = normalize(b);

  int na = -1, nb = -1;

  rrep(i, deg) {
    if (na == -1 and a[i] != 0)
      na = i;
    if (nb == -1 and b[i] != 0)
      nb = i;
  }

  if (nb == -1)
    return a;
  if (nb > na)
    return gcd(b, a);
  if (na == nb and b[nb] > a[na])
    return gcd(b, a);

  const int g = __gcd(a[na], b[nb]);

  int m = b[nb] / g;
  P ret = a;
  rep(i, deg) ret[i] *= m;

  int coef = ret[na] / b[nb];
  rep(i, nb + 1) ret[na - nb + i] -= coef * b[i];

  ret = normalize(ret);
  return gcd(b, ret);
}

int main(void) {
  string s[2];
  while (cin >> s[0] >> s[1]) {
    if (s[0] == ".")
      break;

    int cur = 0;
    P a = expression(s[0], cur);
    cur = 0;
    P b = expression(s[1], cur);
    P res = gcd(a, b);
    output(res);
  }

  return 0;
}

Error: 0

Fixed submission:

#include <bits/stdc++.h>

#define _overload(_1, _2, _3, name, ...) name
#define _rep(i, n) _range(i, 0, n)
#define _range(i, a, b) for (int i = int(a); i < int(b); ++i)
#define rep(...) _overload(__VA_ARGS__, _range, _rep, )(__VA_ARGS__)

#define _rrep(i, n) _rrange(i, n, 0)
#define _rrange(i, a, b) for (int i = int(a) - 1; i >= int(b); --i)
#define rrep(...) _overload(__VA_ARGS__, _rrange, _rrep, )(__VA_ARGS__)

#define _all(arg) begin(arg), end(arg)
#define uniq(arg) sort(_all(arg)), (arg).erase(unique(_all(arg)), end(arg))
#define getidx(ary, key) lower_bound(_all(ary), key) - begin(ary)
#define clr(a, b) memset((a), (b), sizeof(a))
#define bit(n) (1LL << (n))
#define popcount(n) (__builtin_popcountll(n))

using namespace std;

template <class T> bool chmax(T &a, const T &b) {
  return (a < b) ? (a = b, 1) : 0;
}
template <class T> bool chmin(T &a, const T &b) {
  return (b < a) ? (a = b, 1) : 0;
}

using ll = long long;
using R = long double;
const R EPS = 1e-9L; // [-1000,1000]->EPS=1e-8 [-10000,10000]->EPS=1e-7
inline int sgn(const R &r) { return (r > EPS) - (r < -EPS); }
inline R sq(R x) { return sqrt(max(x, 0.0L)); }

const int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
const int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};

// Problem Specific Parameter:

const int deg = 11;
using P = array<int, deg>;
P primary(const string &, int &);
P factor(const string &, int &);
P term(const string &, int &);
P expression(const string &, int &);

int number(const string &s, int &cur) {
  int ret = s[cur++] - '0';
  while (isdigit(s[cur])) {
    ret = 10 * ret + s[cur++] - '0';
  }
  return ret;
}

P mul(P a, P b) {
  P ret;
  fill(begin(ret), end(ret), 0);

  rep(i, deg) rep(j, deg) {
    if (i + j >= deg)
      continue;
    ret[i + j] += a[i] * b[j];
  }
  return ret;
}

P primary(const string &s, int &cur) {
  P ret;
  fill(begin(ret), end(ret), 0);

  if (s[cur] == 'x') {
    cur++;
    ret[1] = 1;
  } else if (s[cur] == '(') {
    cur++;
    ret = expression(s, cur);
    cur++;
  } else if (isdigit(s[cur])) {
    ret[0] = number(s, cur);
  } else {
    assert(false);
  }

  return ret;
}

P factor(const string &s, int &cur) {
  P ret = primary(s, cur);
  if (s[cur] == '^') {
    cur++;
    int idx = number(s, cur);
    P tmp = ret;
    rep(loop, idx - 1) ret = mul(ret, tmp);
  }
  return ret;
}

P term(const string &s, int &cur) {
  P ret = factor(s, cur);
  while (s[cur] == 'x' or s[cur] == '(') {
    ret = mul(ret, factor(s, cur));
  }
  return ret;
}

P expression(const string &s, int &cur) {
  bool minus = false;
  if (s[cur] == '-') {
    cur++;
    minus = true;
  }

  P ret = term(s, cur);
  if (minus) {
    rep(i, deg) ret[i] *= -1;
  }

  while (s[cur] == '+' or s[cur] == '-') {
    char op = s[cur++];
    P tmp = term(s, cur);
    if (op == '+') {
      rep(i, deg) ret[i] = ret[i] + tmp[i];
    } else {
      rep(i, deg) ret[i] = ret[i] - tmp[i];
    }
  }

  return ret;
}

P gcd(P a, P b) {

  int na = -1, nb = -1;

  rrep(i, deg) {
    if (na == -1 and a[i] != 0)
      na = i;
    if (nb == -1 and b[i] != 0)
      nb = i;
  }

  if (nb > na)
    return gcd(b, a);
  if (na == nb and b[nb] > a[na])
    return gcd(b, a);

  int coef = a[na] / b[nb];

  P ret = a;
  rep(i, nb + 1) ret[na - nb + i] -= coef * b[i];

  int g = 0;
  rep(i, deg) g = __gcd(g, ret[i]);

  if (g == 0)
    return b;
  rep(i, deg) ret[i] /= g;

  return gcd(b, ret);
}

void output(P res) {

  bool start = false;

  int ng = -1;
  rrep(i, deg) if (ng == -1 and res[i] != 0) ng = i;

  if (res[ng] < 0) {
    rep(i, deg) res[i] *= -1;
  }

  rrep(i, deg) {
    if (res[i] == 0)
      continue;

    if (start) {
      if (res[i] > 0)
        cout << "+";
      else
        cout << "-";
    }

    if (i == 0 or abs(res[i]) != 1)
      cout << abs(res[i]);

    if (i >= 1) {
      cout << "x";
      if (i >= 2)
        cout << "^" << i;
    }

    start = true;
  }

  cout << endl;
}

int main(void) {
  string s[2];
  while (cin >> s[0] >> s[1]) {
    if (s[0] == ".")
      break;

    int cur = 0;
    P a = expression(s[0], cur);
    cur = 0;
    P b = expression(s[1], cur);

    P res = gcd(a, b);
    output(res);
  }

  return 0;
}