Problem p02950 (C++)

Buggy submission (status: Time Limit Exceeded):
/**
 * code generated by JHelper
 * More info: https://github.com/AlexeyDmitriev/JHelper
 * @author
 */

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define fr(i, n) for (int i = 0; i < (n); ++i)
#define Fr(i, n) for (int i = 1; i <= (n); ++i)
#define ifr(i, n) for (int i = (n)-1; i >= 0; --i)
#define iFr(i, n) for (int i = (n); i > 0; --i)

ll MOD;
struct modint {
  ll a;
  modint(ll a_ = 0) { a = ((a_ % MOD) + MOD) % MOD; }
  modint inv() const {
    ll n = 1, m = MOD - 2, A = a;
    while (m) {
      if (m & 1)
        (n *= A) %= MOD;
      (A *= A) %= MOD;
      m >>= 1;
    }
    modint y(n);
    return y;
  }
  bool operator==(const modint &x) { return a == x.a; }
  bool operator!=(const modint &x) { return a != x.a; }
  modint &operator=(const modint &x) {
    a = x.a;
    return *this;
  }
  modint operator+(const modint &x) {
    modint y(a + x.a);
    return y;
  }
  modint operator-(const modint &x) {
    modint y(a - x.a);
    return y;
  }
  modint operator*(const modint &x) {
    modint y(a * x.a);
    return y;
  }
  modint operator/(const modint &x) { return *this * x.inv(); }
  modint &operator+=(const modint &x) {
    *this = *this + x;
    return *this;
  }
  modint &operator-=(const modint &x) {
    *this = *this - x;
    return *this;
  }
  modint &operator*=(const modint &x) {
    *this = *this * x;
    return *this;
  }
  modint &operator/=(const modint &x) {
    *this = *this / x;
    return *this;
  }
};
istream &operator>>(istream &in, modint &x) {
  ll a_;
  in >> a_;
  modint y(a_);
  x = y;
  return in;
}
ostream &operator<<(ostream &out, const modint &x) {
  out << x.a;
  return out;
}
modint pwr(ll a, ll b) {
  modint n(1), A(a);
  while (b) {
    if (b & 1)
      n *= A;
    A *= A;
    b >>= 1;
  }
  return n;
}

template <class T> struct poly {
  int n;
  vector<T> p;
  poly(vector<T> &v) {
    n = v.size() - 1;
    p = v;
    while (*p.rbegin() == T(0) && n > 0)
      --n, p.pop_back();
  }
  poly(T a = 0) {
    n = 0;
    p = vector<T>(1, a);
  }
  poly &operator+=(const poly &x) {
    n = max(n, x.n);
    p.resize(n + 1);
    for (int i = 0; i < x.p.size(); ++i)
      p[i] += x.p[i];
    while (*p.rbegin() == T(0) && n > 0)
      --n, p.pop_back();
    return *this;
  }
  poly &operator-=(const poly &x) {
    n = max(n, x.n);
    p.resize(n + 1);
    for (int i = 0; i < x.p.size(); ++i)
      p[i] -= x.p[i];
    while (*p.rbegin() == T(0) && n > 0)
      --n, p.pop_back();
    return *this;
  }
  poly operator*(const poly &x) {
    vector<T> q(n + x.n + 1);
    for (int i = 0; i <= n; ++i)
      for (int j = 0; j <= x.n; ++j)
        q[i + j] += p[i] * x.p[i];
    while (*q.rbegin() == T(0) && n > 0)
      q.pop_back();
    return poly(q);
  }
  poly operator/(const poly &x) {
    if (n < x.n)
      return *this;
    T k = T(1) / *x.p.rbegin();
    vector<T> v(n - x.n + 1), q = p;
    for (int i = n - x.n; i >= 0; --i) {
      if (q[i + x.n] == T(0)) {
        v[i] = T(0);
        continue;
      }
      v[i] = q[i + x.n] * k;
      for (int j = 0; j < x.n; ++j)
        q[i + j] -= v[i] * x.p[j];
    }
    return poly(v);
  }
  poly operator+(const poly &x) {
    poly y = *this;
    return y += x;
  }
  poly operator-(const poly &x) {
    poly y = *this;
    return y -= x;
  }
  poly &operator*=(const poly &x) { return *this = *this * x; }
  poly &operator/=(const poly &x) { return *this = *this / x; }
  T operator()(T x) {
    T c(1), a(0);
    for (int i = 0; i <= n; ++i)
      a += p[i] * c, c *= x;
    return a;
  }
};

class FPolynomialConstruction {
public:
  void solve(istream &in, ostream &out) {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int p;
    in >> p;
    MOD = p;
    vector<int> a(p);
    for (auto &i : a)
      in >> i;
    vector<modint> v(p + 1), b(2);
    v[p] = 1;
    v[1] = -1;
    b[1] = 1;
    poly<modint> xpmp(v), ans, tmp;
    fr(i, p) {
      if (a[i] == 0)
        continue;
      b[0] = -i;
      tmp = xpmp / b;
      ans += tmp / tmp(i);
    }
    vector<modint> an = ans.p;
    an.resize(p);
    fr(i, p) out << an[i] << " ";
    out << endl;
  }
};

int main() {
  FPolynomialConstruction solver;
  std::istream &in(std::cin);
  std::ostream &out(std::cout);
  solver.solve(in, out);
  return 0;
}


Fixed submission:
/**
 * code generated by JHelper
 * More info: https://github.com/AlexeyDmitriev/JHelper
 * @author
 */

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define fr(i, n) for (int i = 0; i < (n); ++i)
#define Fr(i, n) for (int i = 1; i <= (n); ++i)
#define ifr(i, n) for (int i = (n)-1; i >= 0; --i)
#define iFr(i, n) for (int i = (n); i > 0; --i)

ll MOD;
struct modint {
  ll a;
  modint(ll a_ = 0) { a = ((a_ % MOD) + MOD) % MOD; }
  modint inv() const {
    ll n = 1, m = MOD - 2, A = a;
    while (m) {
      if (m & 1)
        (n *= A) %= MOD;
      (A *= A) %= MOD;
      m >>= 1;
    }
    modint y(n);
    return y;
  }
  bool operator==(const modint &x) { return a == x.a; }
  bool operator!=(const modint &x) { return a != x.a; }
  modint &operator=(const modint &x) {
    a = x.a;
    return *this;
  }
  modint operator+(const modint &x) {
    modint y(a + x.a);
    return y;
  }
  modint operator-(const modint &x) {
    modint y(a - x.a);
    return y;
  }
  modint operator*(const modint &x) {
    modint y(a * x.a);
    return y;
  }
  modint operator/(const modint &x) { return *this * x.inv(); }
  modint &operator+=(const modint &x) {
    *this = *this + x;
    return *this;
  }
  modint &operator-=(const modint &x) {
    *this = *this - x;
    return *this;
  }
  modint &operator*=(const modint &x) {
    *this = *this * x;
    return *this;
  }
  modint &operator/=(const modint &x) {
    *this = *this / x;
    return *this;
  }
};
istream &operator>>(istream &in, modint &x) {
  ll a_;
  in >> a_;
  modint y(a_);
  x = y;
  return in;
}
ostream &operator<<(ostream &out, const modint &x) {
  out << x.a;
  return out;
}
modint pwr(ll a, ll b) {
  modint n(1), A(a);
  while (b) {
    if (b & 1)
      n *= A;
    A *= A;
    b >>= 1;
  }
  return n;
}

template <class T> struct poly {
  int n;
  vector<T> p;
  poly(vector<T> &v) {
    n = v.size() - 1;
    p = v;
    while (*p.rbegin() == T(0) && n > 0)
      --n, p.pop_back();
  }
  poly(T a = 0) {
    n = 0;
    p = vector<T>(1, a);
  }
  poly &operator+=(const poly &x) {
    n = max(n, x.n);
    p.resize(n + 1);
    for (int i = 0; i < x.p.size(); ++i)
      p[i] += x.p[i];
    while (*p.rbegin() == T(0) && n > 0)
      --n, p.pop_back();
    return *this;
  }
  poly &operator-=(const poly &x) {
    n = max(n, x.n);
    p.resize(n + 1);
    for (int i = 0; i < x.p.size(); ++i)
      p[i] -= x.p[i];
    while (*p.rbegin() == T(0) && n > 0)
      --n, p.pop_back();
    return *this;
  }
  poly operator*(const poly &x) {
    vector<T> q(n + x.n + 1);
    for (int i = 0; i <= n; ++i)
      for (int j = 0; j <= x.n; ++j)
        q[i + j] += p[i] * x.p[i];
    while (*q.rbegin() == T(0) && n > 0)
      q.pop_back();
    return poly(q);
  }
  poly operator/(const poly &x) {
    if (n < x.n)
      return *this;
    T k = T(1) / *x.p.rbegin();
    vector<T> v(n - x.n + 1), q = p;
    for (int i = n - x.n; i >= 0; --i) {
      if (q[i + x.n] == T(0)) {
        v[i] = T(0);
        continue;
      }
      v[i] = q[i + x.n] * k;
      for (int j = 0; j < x.n; ++j)
        q[i + j] -= v[i] * x.p[j];
    }
    return poly(v);
  }
  poly operator+(const poly &x) {
    poly y = *this;
    return y += x;
  }
  poly operator-(const poly &x) {
    poly y = *this;
    return y -= x;
  }
  poly &operator*=(const poly &x) { return *this = *this * x; }
  poly &operator/=(const poly &x) { return *this = *this / x; }
  T operator()(T x) {
    T c(1), a(0);
    for (int i = 0; i <= n; ++i)
      a += p[i] * c, c *= x;
    return a;
  }
};

class FPolynomialConstruction {
public:
  void solve(istream &in, ostream &out) {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int p;
    in >> p;
    MOD = p;
    vector<int> a(p);
    for (auto &i : a)
      in >> i;
    vector<modint> v(p + 1), b(2);
    v[p] = 1;
    v[1] = -1;
    b[1] = 1;
    poly<modint> xpmp(v), ans, tmp;
    fr(i, p) {
      if (a[i] == 0)
        continue;
      b[0] = -i;
      tmp = xpmp / b;
      modint k = modint(1) / tmp(i);
      for (auto &j : tmp.p)
        j *= k;
      ans += tmp;
    }
    vector<modint> an = ans.p;
    an.resize(p);
    fr(i, p) out << an[i] << " ";
    out << endl;
  }
};

int main() {
  FPolynomialConstruction solver;
  std::istream &in(std::cin);
  std::ostream &out(std::cout);
  solver.solve(in, out);
  return 0;
}