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

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < n; i++)
using namespace std;

struct Poly {
  vector<int> c;
  Poly() : c(1, 1) {}
  Poly(int s, int i) : c(s, i) {}
  Poly(vector<int> v) { c = v; }
  int size() const { return c.size(); }

  void print() {

    int flag = 0;

    for (int i = size() - 1; i >= 1; i--) {
      if (c[i]) {
        flag = 1;

        if (c[i] > 0 && i != size() - 1)
          cout << '+';

        if (c[i] == -1)
          cout << '-';
        else if (c[i] != 1)
          cout << c[i];

        cout << 'x';
        if (i != 1)
          cout << "^" << i;
      }
    }

    if (c[0]) {
      if (flag && c[0] > 0)
        cout << "+";
      cout << c[0];
    }

    cout << endl;
  }

  void fit() {
    int s = 1;
    for (int i = size() - 1; i >= 0; i--)
      if (c[i] != 0) {
        s = i + 1;
        break;
      }
    c.resize(s);
  }
  int operator[](int index) const {
    assert(index >= 0 && index < size());
    return c[index];
  }
  int &operator[](int index) {
    assert(index >= 0 && index < size());
    return c[index];
  }
  Poly operator-() const {
    Poly ret = *this;
    rep(i, ret.size()) ret[i] = -ret[i];
    // ret.fit();
    return ret;
  }
  Poly operator*(const Poly &rhs) const {
    Poly ret(size() + rhs.size(), 0);
    rep(i, size()) rep(j, rhs.size()) ret[i + j] += c[i] * rhs[j];
    ret.fit();
    return ret;
  }
  Poly operator+(const Poly &a) const {
    Poly res = *this;
    int A = a.size();
    res.c.resize(max(size(), A));
    rep(i, A) res[i] = res[i] + a[i];
    res.fit();
    return res;
  }
  void reduce() {
    int g = abs(c.back());
    if (g > 0) {
      for (int j : c)
        if (j != 0)
          g = __gcd(g, abs(j));
      if (c.back() < 0)
        g = -g;
      for (int &j : c)
        j /= g;
    }
  }
  Poly pow(int power) const {
    Poly base = *this;
    Poly res;
    while (power > 0) {
      if (power & 1)
        res = res * base;
      base = base * base;
      power >>= 1;
    }
    return res;
  }
  pair<Poly, Poly> DIV(const Poly &rhs) const {
    int ls = size(), rs = rhs.size(), s = ls - rs + 1;
    if (s < 0) {
      return make_pair(Poly(1, 0), *this);
    }
    Poly div(s, 0), rest = *this;
    assert(rhs[rs - 1] != 0);
    rep(i, s) {
      if (rest[ls - i - 1] % rhs[rs - 1] != 0) //
        for (auto &j : rest.c)
          j *= rhs[rs - 1]; //
      int d = rest[ls - i - 1] / rhs[rs - 1];
      div[s - i - 1] = d;
      rep(j, rs) rest[ls - i - j - 1] -= rhs[rs - j - 1] * d;
    }
    div.fit();
    rest.fit();
    rest.reduce(); //
    return make_pair(div, rest);
  }
  Poly operator%(const Poly &a) const { return DIV(a).second; }
  Poly operator-(const Poly &a) const { return *this + (-a); }
};
Poly PolyGCD(Poly a, Poly b) {
  if (b.size() == 1 && b[0] == 0) {
    a.reduce();
    return a;
  }
  return PolyGCD(b, a % b);
}

int p;
string s;

Poly bnf1();

Poly g_A() {
  if (s[p] == '(') {
    p++;
    Poly res = bnf1();
    p++;

    int num2 = 0;

    if (s[p] == '^') {
      p++;
      while ('0' <= s[p] && s[p] <= '9')
        num2 = num2 * 10 + s[p++] - '0';
    }

    // Poly tmp(1,num2);

    if (num2)
      res = res.pow(num2);

    return res;
  } else {

    int num = 0;

    while ('0' <= s[p] && s[p] <= '9')
      num = num * 10 + s[p++] - '0';

    if (p < s.size() && s[p] == 'x') {

      if (num == 0)
        num = 1;

      p++;

      int num2 = 0;

      vector<int> v;

      if (p < s.size() && s[p] == '^') {
        p++;
        while ('0' <= s[p] && s[p] <= '9')
          num2 = num2 * 10 + s[p++] - '0';
      }

      if (num2 == 0) {
        v.resize(2, 0);
        v[1] = num;
        Poly res(v);
        // res.print();
        return res;
      } else {
        v.resize(num2 + 1, 0);
        v[num2] = num;
        Poly res(v);
        return res;
      }
    } else {

      Poly res(1, num);
      return res;
    }
  }
}

Poly bnf2() {
  Poly res = g_A();
  while (p < s.size() && s[p] == '*') {
    int t = p++;
    if (s[t] == '*') {
      res = res * g_A();
    }
  }
  return res;
}

Poly bnf1() {
  Poly res = bnf2();

  while (p < s.size() && s[p] == '+' || s[p] == '-') {
    int t = p++;
    if (s[t] == '+') {
      res = res + bnf2();
    }
    if (s[t] == '-') {
      Poly r = bnf2();

      res = res - r;
    }
  }
  return res;
}

Poly parse(string s) {
  p = 0;
  return bnf1();
}

string kake(string ss) {
  // cout<<'a'<<endl;
  for (int i = 0; i < (int)ss.size() - 1; i++) {
    if (ss[i + 1] == '(' && !(ss[i] == '+' || ss[i] == '-' || ss[i] == '*')) {
      ss = ss.substr(0, i + 1) + '*' + ss.substr(i + 1);
    }
    // cout<<ss<<endl;
  }
  // cout<<'b'<<endl;
  if (ss[0] == '-') {
    ss = "0" + ss;
  }

  return ss;
}

std::chrono::system_clock::time_point start;
std::chrono::system_clock::time_point owari;

signed main() {
  while (cin >> s, s != ".") {
    s = kake(s);
    // cout<<s<<endl;
    // return 0;
    Poly a1 = parse(s);
    // a1.print();
    cin >> s;
    s = kake(s);
    Poly a2 = parse(s);
    Poly po = PolyGCD(a1, a2);
    po.print();
  }
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < n; i++)
using namespace std;

struct Poly {
  vector<int> c;
  Poly() : c(1, 1) {}
  Poly(int s, int i) : c(s, i) {}
  Poly(vector<int> v) { c = v; }
  int size() const { return c.size(); }

  void print() {

    int flag = 0;

    for (int i = size() - 1; i >= 1; i--) {
      if (c[i]) {
        flag = 1;

        if (c[i] > 0 && i != size() - 1)
          cout << '+';

        if (c[i] == -1)
          cout << '-';
        else if (c[i] != 1)
          cout << c[i];

        cout << 'x';
        if (i != 1)
          cout << "^" << i;
      }
    }

    if (c[0]) {
      if (flag && c[0] > 0)
        cout << "+";
      cout << c[0];
    }

    cout << endl;
  }

  void fit() {
    int s = 1;
    for (int i = size() - 1; i >= 0; i--)
      if (c[i] != 0) {
        s = i + 1;
        break;
      }
    c.resize(s);
  }
  int operator[](int index) const {
    assert(index >= 0 && index < size());
    return c[index];
  }
  int &operator[](int index) {
    assert(index >= 0 && index < size());
    return c[index];
  }
  Poly operator-() const {
    Poly ret = *this;
    rep(i, ret.size()) ret[i] = -ret[i];
    // ret.fit();
    return ret;
  }
  Poly operator*(const Poly &rhs) const {
    Poly ret(size() + rhs.size(), 0);
    rep(i, size()) rep(j, rhs.size()) ret[i + j] += c[i] * rhs[j];
    ret.fit();
    return ret;
  }
  Poly operator+(const Poly &a) const {
    Poly res = *this;
    int A = a.size();
    res.c.resize(max(size(), A));
    rep(i, A) res[i] = res[i] + a[i];
    res.fit();
    return res;
  }
  void reduce() {
    int g = abs(c.back());
    if (g > 0) {
      for (int j : c)
        if (j != 0)
          g = __gcd(g, abs(j));
      if (c.back() < 0)
        g = -g;
      for (int &j : c)
        j /= g;
    }
  }
  Poly pow(int power) const {
    Poly base = *this;
    Poly res;
    while (power > 0) {
      if (power & 1)
        res = res * base;
      base = base * base;
      power >>= 1;
    }
    return res;
  }
  pair<Poly, Poly> DIV(const Poly &rhs) const {
    int ls = size(), rs = rhs.size(), s = ls - rs + 1;
    if (s < 0) {
      return make_pair(Poly(1, 0), *this);
    }
    Poly div(s, 0), rest = *this;
    assert(rhs[rs - 1] != 0);
    rep(i, s) {
      if (rest[ls - i - 1] % rhs[rs - 1] != 0) //
        for (auto &j : rest.c)
          j *= rhs[rs - 1]; //
      int d = rest[ls - i - 1] / rhs[rs - 1];
      div[s - i - 1] = d;
      rep(j, rs) rest[ls - i - j - 1] -= rhs[rs - j - 1] * d;
    }
    div.fit();
    rest.fit();
    rest.reduce(); //
    return make_pair(div, rest);
  }
  Poly operator%(const Poly &a) const { return DIV(a).second; }
  Poly operator-(const Poly &a) const { return *this + (-a); }
};
Poly PolyGCD(Poly a, Poly b) {
  if (b.size() == 1 && b[0] == 0) {
    a.reduce();
    return a;
  }
  return PolyGCD(b, a % b);
}

int p;
string s;

Poly bnf1();

Poly g_A() {
  if (s[p] == '(') {
    p++;
    Poly res = bnf1();
    p++;

    int num2 = 0;

    if (s[p] == '^') {
      p++;
      while ('0' <= s[p] && s[p] <= '9')
        num2 = num2 * 10 + s[p++] - '0';
    }

    // Poly tmp(1,num2);

    if (num2)
      res = res.pow(num2);

    return res;
  } else {

    int num = 0;

    while ('0' <= s[p] && s[p] <= '9')
      num = num * 10 + s[p++] - '0';

    if (p < s.size() && s[p] == 'x') {

      if (num == 0)
        num = 1;

      p++;

      int num2 = 0;

      vector<int> v;

      if (p < s.size() && s[p] == '^') {
        p++;
        while ('0' <= s[p] && s[p] <= '9')
          num2 = num2 * 10 + s[p++] - '0';
      }

      if (num2 == 0) {
        v.resize(2, 0);
        v[1] = num;
        Poly res(v);
        // res.print();
        return res;
      } else {
        v.resize(num2 + 1, 0);
        v[num2] = num;
        Poly res(v);
        return res;
      }
    } else {

      Poly res(1, num);
      return res;
    }
  }
}

Poly bnf2() {
  Poly res = g_A();
  while (p < s.size() && s[p] == '*') {
    int t = p++;
    if (s[t] == '*') {
      res = res * g_A();
    }
  }
  return res;
}

Poly bnf1() {
  Poly res = bnf2();

  while (p < s.size() && s[p] == '+' || s[p] == '-') {
    int t = p++;
    if (s[t] == '+') {
      res = res + bnf2();
    }
    if (s[t] == '-') {
      Poly r = bnf2();

      res = res - r;
    }
  }
  return res;
}

Poly parse(string s) {
  p = 0;
  return bnf1();
}

string kake(string ss) {
  for (int i = 0; i < (int)ss.size() - 1; i++) {
    if (ss[i + 1] == '(' && !(ss[i] == '+' || ss[i] == '-' || ss[i] == '*')) {
      ss = ss.substr(0, i) + '*' + ss.substr(i);
      i--;
    }
  }
  if (ss[0] == '-') {
    ss = "0" + ss;
  }

  return ss;
}

signed main() {
  while (cin >> s, s != ".") {
    s = kake(s);
    Poly a1 = parse(s);
    cin >> s;
    s = kake(s);
    Poly a2 = parse(s);
    Poly po = PolyGCD(a1, a2);
    po.print();
  }
}