Problem p00872 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>

using namespace std;

#define LOG(...) fprintf(stderr, __VA_ARGS__)
// #define LOG(...)
#define FOR(i, a, b) for (int i = (int)(a); i < (int)(b); ++i)
#define RFOR(i, a, b) for (int i = (int)(b - 1); i >= (int)(a); --i)
#define REP(i, n) for (int i = 0; i < (int)(n); ++i)
#define RREP(i, n) for (int i = (int)(n - 1); i >= 0; --i)
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define EXIST(s, e) ((s).find(e) != (s).end())
#define SORT(c) sort(ALL(c))
#define RSORT(c) sort(RALL(c))
#define SZ(a) ((int)(a).size())
#define BIT(x, i) (((x) >> (i)) & 1)
#define SQ(x) ((x) * (x))

typedef long long ll;
typedef unsigned long long ull;
typedef vector<bool> vb;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<vb> vvb;
typedef vector<vi> vvi;
typedef vector<vll> vvll;
typedef vector<char> vc;
typedef vector<vc> vvc;
typedef vector<string> vs;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

struct Poly {
  vi coefs;

  Poly() { coefs.resize(10, 0); }

  Poly(const Poly &p) { coefs = p.coefs; }

  Poly &operator+=(const Poly &q) {
    REP(i, 10) { coefs[i] += q.coefs[i]; }
    return *this;
  }

  Poly &operator-=(const Poly &q) {
    REP(i, 10) { coefs[i] -= q.coefs[i]; }
    return *this;
  }

  Poly &operator*=(const Poly &q) {
    vi c(10);
    REP(i, 10) REP(j, 10) { c[i + j] += coefs[i] * q.coefs[j]; }
    coefs = c;
    return *this;
  }

  Poly &operator*=(int n) {
    REP(i, 10) { coefs[i] *= n; }
    return *this;
  }

  Poly operator%(Poly q) {
    Poly p(*this);
    int x = p.highest_degree(), y = q.highest_degree();
    int a = p.coefs[x], b = q.coefs[y];
    if (x > y) {
      Poly v;
      v.coefs[y - x] = 1;
      p *= v;
      x = y;
    }
    if (a != b) {
      p *= b;
      q *= a;
    }
    RREP(i, x - y + 1) {
      Poly r;
      r.coefs[i] = p.coefs[i + y] / q.coefs[y];
      r *= q;
      p -= r;
    }
    return p;
  }

  bool is_zero() {
    REP(i, 10) {
      if (coefs[i] != 0)
        return false;
    }
    return true;
  }

  int highest_degree() {
    RREP(i, 10) {
      if (coefs[i] != 0)
        return i;
    }
    return 0;
  }

  void reduce() {
    RFOR(i, 2, 100) {
      bool divisiable = true;
      REP(j, 10) {
        if (coefs[j] != 0) {
          if (coefs[j] % i != 0) {
            divisiable = false;
            break;
          }
        }
      }
      if (divisiable) {
        REP(j, 10) { coefs[j] /= i; }
      }
    }
  }

  string dump() {
    stringstream ss;
    bool f = false;
    int degree = highest_degree();
    if (coefs[degree] < 0) {
      REP(i, 10) { coefs[i] *= -1; }
    }
    RREP(i, 10) {
      if (coefs[i] != 0) {
        if (f && coefs[i] > 0)
          ss << "+";
        if (i > 0) {
          if (coefs[i] == -1) {
            ss << "-";
          } else if (coefs[i] != 1) {
            ss << coefs[i];
          }
          ss << "x";
          if (i > 1)
            ss << "^" << i;
        } else {
          ss << coefs[i];
        }
        f = true;
      }
    }
    if (!f)
      ss << "0";
    return ss.str();
  }
};

Poly gcd(Poly p, Poly q) {
  if (q.is_zero())
    return p;
  return gcd(q, p % q);
}

Poly expr(string &s, int &idx);
Poly term(string &s, int &idx);
Poly factor(string &s, int &idx);
Poly primary(string &s, int &idx);
int number(string &s, int &idx);

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

Poly primary(string &s, int &idx) {
  Poly p;
  if (s[idx] == 'x') {
    idx++;
    p.coefs[1] = 1;
  } else if (s[idx] == '(') {
    idx++;
    p = expr(s, idx);
    idx++;
  } else {
    p.coefs[0] = number(s, idx);
  }
  return p;
}

Poly factor(string &s, int &idx) {
  Poly p = primary(s, idx);
  if (s[idx] == '^') {
    idx++;
    int n = number(s, idx);
    Poly q = p;
    REP(i, n - 1) { p *= q; }
  }
  return p;
}

Poly term(string &s, int &idx) {
  Poly p = factor(s, idx);
  for (; idx < (int)s.length();) {
    if (s[idx] == ')' || s[idx] == '+' || s[idx] == '-') {
      return p;
    } else {
      Poly q = factor(s, idx);
      p *= q;
    }
  }
  return p;
}

Poly expr(string &s, int &idx) {
  Poly p;
  for (; idx < (int)s.length();) {
    if (s[idx] == ')') {
      return p;
    } else if (s[idx] == '+') {
      idx++;
      Poly q = term(s, idx);
      p += q;
    } else if (s[idx] == '-') {
      idx++;
      Poly q = term(s, idx);
      p -= q;
    } else {
      Poly q = term(s, idx);
      p += q;
    }
  }
  return p;
}

int main() {

  string s1;
  while (cin >> s1, s1 != ".") {
    string s2;
    cin >> s2;
    int idx = 0;
    Poly p1 = expr(s1, idx);
    idx = 0;
    Poly p2 = expr(s2, idx);

    Poly ans = gcd(p1, p2);
    ans.reduce();
    cout << ans.dump() << endl;
  }
}

Fixed submission:
#include <bits/stdc++.h>

using namespace std;

#define LOG(...) fprintf(stderr, __VA_ARGS__)
// #define LOG(...)
#define FOR(i, a, b) for (int i = (int)(a); i < (int)(b); ++i)
#define RFOR(i, a, b) for (int i = (int)(b - 1); i >= (int)(a); --i)
#define REP(i, n) for (int i = 0; i < (int)(n); ++i)
#define RREP(i, n) for (int i = (int)(n - 1); i >= 0; --i)
#define ALL(a) (a).begin(), (a).end()
#define RALL(a) (a).rbegin(), (a).rend()
#define EXIST(s, e) ((s).find(e) != (s).end())
#define SORT(c) sort(ALL(c))
#define RSORT(c) sort(RALL(c))
#define SZ(a) ((int)(a).size())
#define BIT(x, i) (((x) >> (i)) & 1)
#define SQ(x) ((x) * (x))

typedef long long ll;
typedef unsigned long long ull;
typedef vector<bool> vb;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<vb> vvb;
typedef vector<vi> vvi;
typedef vector<vll> vvll;
typedef vector<char> vc;
typedef vector<vc> vvc;
typedef vector<string> vs;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

struct Poly {
  vi coefs;

  Poly() { coefs.resize(10, 0); }

  Poly(const Poly &p) { coefs = p.coefs; }

  Poly &operator+=(const Poly &q) {
    REP(i, 10) { coefs[i] += q.coefs[i]; }
    return *this;
  }

  Poly &operator-=(const Poly &q) {
    REP(i, 10) { coefs[i] -= q.coefs[i]; }
    return *this;
  }

  Poly &operator*=(const Poly &q) {
    vi c(10);
    REP(i, 10) REP(j, 10) { c[i + j] += coefs[i] * q.coefs[j]; }
    coefs = c;
    return *this;
  }

  Poly &operator*=(int n) {
    REP(i, 10) { coefs[i] *= n; }
    return *this;
  }

  Poly operator%(Poly q) {
    Poly p(*this);
    int x = p.highest_degree(), y = q.highest_degree();
    int a = p.coefs[x], b = q.coefs[y];
    if (x > y) {
      //            Poly v;
      //            v.coefs[x-y] = 1;
      //            q *= v;
      //            y = x;
    } else if (x > y) {
      Poly v;
      v.coefs[y - x] = 1;
      p *= v;
      x = y;
    }
    if (a != b) {
      p *= b;
      q *= a;
    }
    RREP(i, x - y + 1) {
      Poly r;
      r.coefs[i] = p.coefs[i + y] / q.coefs[y];
      r *= q;
      p -= r;
    }
    return p;
  }

  bool is_zero() {
    REP(i, 10) {
      if (coefs[i] != 0)
        return false;
    }
    return true;
  }

  int highest_degree() {
    RREP(i, 10) {
      if (coefs[i] != 0)
        return i;
    }
    return 0;
  }

  void reduce() {
    RFOR(i, 2, 100) {
      bool divisiable = true;
      REP(j, 10) {
        if (coefs[j] != 0) {
          if (coefs[j] % i != 0) {
            divisiable = false;
            break;
          }
        }
      }
      if (divisiable) {
        REP(j, 10) { coefs[j] /= i; }
      }
    }
  }

  string dump() {
    stringstream ss;
    bool f = false;
    int degree = highest_degree();
    if (coefs[degree] < 0) {
      REP(i, 10) { coefs[i] *= -1; }
    }
    RREP(i, 10) {
      if (coefs[i] != 0) {
        if (f && coefs[i] > 0)
          ss << "+";
        if (i > 0) {
          if (coefs[i] == -1) {
            ss << "-";
          } else if (coefs[i] != 1) {
            ss << coefs[i];
          }
          ss << "x";
          if (i > 1)
            ss << "^" << i;
        } else {
          ss << coefs[i];
        }
        f = true;
      }
    }
    if (!f)
      ss << "0";
    return ss.str();
  }
};

Poly gcd(Poly p, Poly q) {
  if (q.is_zero())
    return p;
  return gcd(q, p % q);
}

Poly expr(string &s, int &idx);
Poly term(string &s, int &idx);
Poly factor(string &s, int &idx);
Poly primary(string &s, int &idx);
int number(string &s, int &idx);

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

Poly primary(string &s, int &idx) {
  Poly p;
  if (s[idx] == 'x') {
    idx++;
    p.coefs[1] = 1;
  } else if (s[idx] == '(') {
    idx++;
    p = expr(s, idx);
    idx++;
  } else {
    p.coefs[0] = number(s, idx);
  }
  return p;
}

Poly factor(string &s, int &idx) {
  Poly p = primary(s, idx);
  if (s[idx] == '^') {
    idx++;
    int n = number(s, idx);
    Poly q = p;
    REP(i, n - 1) { p *= q; }
  }
  return p;
}

Poly term(string &s, int &idx) {
  Poly p = factor(s, idx);
  for (; idx < (int)s.length();) {
    if (s[idx] == ')' || s[idx] == '+' || s[idx] == '-') {
      return p;
    } else {
      Poly q = factor(s, idx);
      p *= q;
    }
  }
  return p;
}

Poly expr(string &s, int &idx) {
  Poly p;
  for (; idx < (int)s.length();) {
    if (s[idx] == ')') {
      return p;
    } else if (s[idx] == '+') {
      idx++;
      Poly q = term(s, idx);
      p += q;
    } else if (s[idx] == '-') {
      idx++;
      Poly q = term(s, idx);
      p -= q;
    } else {
      Poly q = term(s, idx);
      p += q;
    }
  }
  return p;
}

int main() {

  string s1;
  while (cin >> s1, s1 != ".") {
    string s2;
    cin >> s2;
    int idx = 0;
    Poly p1 = expr(s1, idx);
    idx = 0;
    Poly p2 = expr(s2, idx);

    Poly ans = gcd(p1, p2);
    ans.reduce();
    cout << ans.dump() << endl;
  }
}