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

#include <algorithm>
#include <iostream>
#include <string>
#include <utility>
#include <vector>

using namespace std;
typedef long long ll;
typedef pair<vector<ll>, ll> pvi;

vector<ll> polyadd(const vector<ll> &a, const vector<ll> &b) {
  const ll n = a.size(), m = b.size();
  vector<ll> result(max(n, m));
  for (ll i = 0; i < n; ++i) {
    result[i] += a[i];
  }
  for (ll i = 0; i < m; ++i) {
    result[i] += b[i];
  }
  while (!result.empty() && result.back() == 0) {
    result.pop_back();
  }
  return result;
}
vector<ll> polysub(const vector<ll> &a, const vector<ll> &b) {
  const ll n = a.size(), m = b.size();
  vector<ll> result(max(n, m));
  for (ll i = 0; i < n; ++i) {
    result[i] += a[i];
  }
  for (ll i = 0; i < m; ++i) {
    result[i] -= b[i];
  }
  while (!result.empty() && result.back() == 0) {
    result.pop_back();
  }
  return result;
}
vector<ll> polymul(const vector<ll> &a, const vector<ll> &b) {
  const ll n = a.size(), m = b.size();
  if (n == 0 || m == 0) {
    return vector<ll>();
  }
  vector<ll> result(n + m - 1);
  for (ll i = 0; i < n; ++i) {
    for (ll j = 0; j < m; ++j) {
      result[i + j] += a[i] * b[j];
    }
  }
  while (!result.empty() && result.back() == 0) {
    result.pop_back();
  }
  return result;
}
vector<ll> polypow(const vector<ll> &a, ll b) {
  vector<ll> x = a, y(1, 1);
  while (b) {
    if (b & 1) {
      y = polymul(y, x);
    }
    x = polymul(x, x);
    b >>= 1;
  }
  return y;
}

pvi lex_expr(const char *s, ll p);
pvi lex_term(const char *s, ll p);
pvi lex_factor(const char *s, ll p);
pvi lex_digits(const char *s, ll p);

pvi lex_expr(const char *s, ll p) {
  pvi r(vector<ll>(), p);
  if (s[p] != '-') {
    r = lex_term(s, p);
  }
  while (s[r.second] == '+' || s[r.second] == '-') {
    const pvi q = lex_term(s, r.second + 1);
    if (s[r.second] == '+') {
      r.first = polyadd(r.first, q.first);
    } else {
      r.first = polysub(r.first, q.first);
    }
    r.second = q.second;
  }
  return r;
}
pvi lex_term(const char *s, ll p) {
  pvi r = lex_factor(s, p);
  p = r.second;
  while (s[p] != '+' && s[p] != '-' && s[p] != ')' && s[p] != '\\0') {
    const pvi q = lex_factor(s, p);
    r.first = polymul(r.first, q.first);
    p = r.second = q.second;
  }
  return r;
}
pvi lex_factor(const char *s, ll p) {
  pvi r(vector<ll>(), p);
  if (s[p] == '(') {
    r = lex_expr(s, p + 1);
    r.second += 1;
  } else if (s[p] == 'x') {
    r.first = vector<ll>(2);
    r.first[1] = 1;
    r.second = p + 1;
  } else if (isdigit(s[p])) {
    r.first.push_back(0);
    while (isdigit(s[p])) {
      r.first[0] = (r.first[0] * 10) + (s[p++] - '0');
    }
    r.second = p;
  }
  if (s[r.second] == '^') {
    ll x = 0;
    p = r.second + 1;
    while (isdigit(s[p])) {
      x = (x * 10) + (s[p++] - '0');
    }
    r.first = polypow(r.first, x);
    r.second = p;
  }
  return r;
}

vector<ll> polyabs(vector<ll> a) {
  if (!a.empty() && a.back() < 0) {
    for (ll i = 0; i < a.size(); ++i) {
      a[i] *= -1;
    }
  }
  return a;
}

vector<ll> reduction(vector<ll> a) {
  while (!a.empty() && a.back() == 0) {
    a.pop_back();
  }
  if (a.empty()) {
    return a;
  }
  a = polyabs(a);
  ll g = a[0];
  for (ll i = 0; i < a.size(); ++i) {
    g = __gcd(g, abs(a[i]));
  }
  for (ll i = 0; i < a.size(); ++i) {
    a[i] /= g;
  }
  while (!a.empty() && a.back() == 0) {
    a.pop_back();
  }
  return a;
}

vector<ll> polymod(vector<ll> a, vector<ll> b) {
  a = polyabs(a);
  b = polyabs(b);
  if (b.size() <= a.size()) {
    ll g = __gcd(abs(a.back()), abs(b.back()));
    const ll ab = a.back(), bb = b.back();
    a = polymul(a, vector<ll>(1, bb / g));
    b = polymul(b, vector<ll>(1, ab / g));
    const ll d = a.size() - b.size();
    for (ll i = 0; i < b.size(); ++i) {
      a[i + d] -= b[i];
    }
    a = reduction(polyabs(a));
  }
  return a;
}

vector<ll> gcd(const vector<ll> &a, const vector<ll> &b) {
  if (b.empty()) {
    return reduction(a);
  }
  return reduction(gcd(b, polymod(a, b)));
}

int main() {
  ios_base::sync_with_stdio(false);
  while (true) {
    string s, t;
    cin >> s;
    if (s == ".") {
      break;
    }
    cin >> t;
    const vector<ll> a = lex_expr(s.c_str(), 0).first;
    const vector<ll> b = lex_expr(t.c_str(), 0).first;
    const vector<ll> c = gcd(a, b);
    if (c.empty()) {
      cout << "0" << endl;
    }
    for (ll i = c.size() - 1; i >= 0; --i) {
      if (c[i] == 0) {
        continue;
      }
      if (c[i] > 0 && i != c.size() - 1) {
        cout << "+";
      }
      if (i != 0 && c[i] == -1) {
        cout << "-";
      } else if (i == 0 || c[i] != 1) {
        cout << c[i];
      }
      if (i >= 1) {
        cout << "x";
      }
      if (i >= 2) {
        cout << "^" << i;
      }
    }
    cout << endl;
  }
  return 0;
}

Error: 0

Fixed submission:

#include <algorithm>
#include <iostream>
#include <string>
#include <utility>
#include <vector>

using namespace std;
typedef pair<vector<int>, int> pvi;

vector<int> polyadd(const vector<int> &a, const vector<int> &b) {
  const int n = a.size(), m = b.size();
  vector<int> result(max(n, m));
  for (int i = 0; i < n; ++i) {
    result[i] += a[i];
  }
  for (int i = 0; i < m; ++i) {
    result[i] += b[i];
  }
  while (!result.empty() && result.back() == 0) {
    result.pop_back();
  }
  return result;
}
vector<int> polysub(const vector<int> &a, const vector<int> &b) {
  const int n = a.size(), m = b.size();
  vector<int> result(max(n, m));
  for (int i = 0; i < n; ++i) {
    result[i] += a[i];
  }
  for (int i = 0; i < m; ++i) {
    result[i] -= b[i];
  }
  while (!result.empty() && result.back() == 0) {
    result.pop_back();
  }
  return result;
}
vector<int> polymul(const vector<int> &a, const vector<int> &b) {
  const int n = a.size(), m = b.size();
  if (n == 0 || m == 0) {
    return vector<int>();
  }
  vector<int> result(n + m - 1);
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < m; ++j) {
      result[i + j] += a[i] * b[j];
    }
  }
  while (!result.empty() && result.back() == 0) {
    result.pop_back();
  }
  return result;
}
vector<int> polypow(const vector<int> &a, int b) {
  vector<int> x = a, y(1, 1);
  while (b) {
    if (b & 1) {
      y = polymul(y, x);
    }
    x = polymul(x, x);
    b >>= 1;
  }
  return y;
}

pvi lex_expr(const char *s, int p);
pvi lex_term(const char *s, int p);
pvi lex_factor(const char *s, int p);
pvi lex_digits(const char *s, int p);

pvi lex_expr(const char *s, int p) {
  pvi r(vector<int>(), p);
  if (s[p] != '-') {
    r = lex_term(s, p);
  }
  while (s[r.second] == '+' || s[r.second] == '-') {
    const pvi q = lex_term(s, r.second + 1);
    if (s[r.second] == '+') {
      r.first = polyadd(r.first, q.first);
    } else {
      r.first = polysub(r.first, q.first);
    }
    r.second = q.second;
  }
  return r;
}
pvi lex_term(const char *s, int p) {
  pvi r = lex_factor(s, p);
  p = r.second;
  while (s[p] != '+' && s[p] != '-' && s[p] != ')' && s[p] != '\\0') {
    const pvi q = lex_factor(s, p);
    r.first = polymul(r.first, q.first);
    p = r.second = q.second;
  }
  return r;
}
pvi lex_factor(const char *s, int p) {
  pvi r(vector<int>(), p);
  if (s[p] == '(') {
    r = lex_expr(s, p + 1);
    r.second += 1;
  } else if (s[p] == 'x') {
    r.first = vector<int>(2);
    r.first[1] = 1;
    r.second = p + 1;
  } else if (isdigit(s[p])) {
    r.first.push_back(0);
    while (isdigit(s[p])) {
      r.first[0] = (r.first[0] * 10) + (s[p++] - '0');
    }
    r.second = p;
  }
  if (s[r.second] == '^') {
    int x = 0;
    p = r.second + 1;
    while (isdigit(s[p])) {
      x = (x * 10) + (s[p++] - '0');
    }
    r.first = polypow(r.first, x);
    r.second = p;
  }
  return r;
}

vector<int> polyabs(vector<int> a) {
  if (!a.empty() && a.back() < 0) {
    for (int i = 0; i < a.size(); ++i) {
      a[i] *= -1;
    }
  }
  return a;
}

vector<int> reduction(vector<int> a) {
  while (!a.empty() && a.back() == 0) {
    a.pop_back();
  }
  if (a.empty()) {
    return a;
  }
  int g = a[0];
  for (int i = 0; i < a.size(); ++i) {
    g = __gcd(g, abs(a[i]));
  }
  for (int i = 0; i < a.size(); ++i) {
    a[i] /= g;
  }
  while (!a.empty() && a.back() == 0) {
    a.pop_back();
  }
  return a;
}

vector<int> polymod(vector<int> a, vector<int> b) {
  if (b.size() <= a.size()) {
    int g = __gcd(a.back(), b.back());
    a = polymul(a, vector<int>(1, b.back() / g));
    b = polymul(b, vector<int>(1, a.back() / g));
    const int d = a.size() - b.size();
    for (int i = 0; i < b.size(); ++i) {
      a[i + d] -= b[i];
    }
    a = reduction(polyabs(a));
  }
  return a;
}

vector<int> gcd(const vector<int> &a, const vector<int> &b) {
  if (b.empty()) {
    return a;
  }
  return gcd(b, polymod(a, b));
}

int main() {
  ios_base::sync_with_stdio(false);
  while (true) {
    string s, t;
    cin >> s;
    if (s == ".") {
      break;
    }
    cin >> t;
    const vector<int> a = lex_expr(s.c_str(), 0).first;
    const vector<int> b = lex_expr(t.c_str(), 0).first;
    const vector<int> c = gcd(a, b);
    for (int i = c.size() - 1; i >= 0; --i) {
      if (a[i] == 0) {
        continue;
      }
      if (c[i] > 0 && i != c.size() - 1) {
        cout << "+";
      }
      if (i != 0 && c[i] == -1) {
        cout << "-";
      } else if (i == 0 || c[i] != 1) {
        cout << c[i];
      }
      if (i >= 1) {
        cout << "x";
      }
      if (i >= 2) {
        cout << "^" << i;
      }
    }
    cout << endl;
  }
  return 0;
}