Problem p02950 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <deque>
#include <functional>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <stdexcept>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
using namespace std;
using ll = long long;

#include <algorithm>
#include <vector>
namespace ProconLib {

namespace DetailNS {
template <typename T> struct DefaultDetail {
  static bool isZero(T x) { return x <= T(0); }
};
} // namespace DetailNS
template <typename T> class Polynomial {
  int N;
  std::vector<T> dat;

public:
  Polynomial(int N) : N(N), dat(N + 1) {}
  Polynomial() : Polynomial(0) {}
  Polynomial(const Polynomial &obj) : N(N), dat(dat) {}
  // Polynomial(const Polynomial&& obj):N(N),dat(std::move(dat)){}

  int degree() { return N; }
  void resize(int N) {
    this->N = N;
    dat.resize(N + 1, T(0));
  }
  template <typename Detail = DetailNS::DefaultDetail<T>> void shrink();
  T &operator[](int pos) { return dat[pos]; }
  const T &operator[](int pos) const { return dat[pos]; }

  T operator()(T x);
};

template <typename T>
Polynomial<T> &operator+=(Polynomial<T> &lhs, Polynomial<T> rhs);
template <typename T>
Polynomial<T> &operator-=(Polynomial<T> &lhs, Polynomial<T> rhs);
template <typename T>
Polynomial<T> &operator*=(Polynomial<T> &lhs, Polynomial<T> rhs);
template <typename T>
Polynomial<T> operator+(Polynomial<T> lhs, Polynomial<T> rhs) {
  return lhs += rhs;
}
template <typename T>
Polynomial<T> operator-(Polynomial<T> lhs, Polynomial<T> rhs) {
  return lhs -= rhs;
}
template <typename T>
Polynomial<T> operator*(Polynomial<T> lhs, Polynomial<T> rhs) {
  return lhs *= rhs;
}

template <typename T> template <typename Detail> void Polynomial<T>::shrink() {
  while (N) {
    if (Detail::isZero(dat[N]))
      N--;
    else
      break;
  }
  resize(N);
}

template <typename T>
Polynomial<T> &operator+=(Polynomial<T> &lhs, Polynomial<T> rhs) {
  lhs.resize(std::max(lhs.degree(), rhs.degree()));
  for (int i = 0; i <= rhs.degree(); i++)
    lhs[i] += rhs[i];
  return lhs;
}

template <typename T>
Polynomial<T> &operator-=(Polynomial<T> &lhs, Polynomial<T> rhs) {
  lhs.resize(std::max(lhs.degree(), rhs.degree()));
  for (int i = 0; i <= rhs.degree(); i++)
    lhs[i] -= rhs[i];
  return lhs;
}

template <typename T>
Polynomial<T> &operator*=(Polynomial<T> &lhs, Polynomial<T> rhs) {
  Polynomial<T> lhsTmp = lhs;
  lhs.resize(lhs.degree() + rhs.degree());
  for (int i = 0; i <= lhsTmp.degree(); i++)
    lhs[i] = T(0);
  for (int i = 0; i <= lhsTmp.degree(); i++) {
    for (int j = 0; j <= rhs.degree(); j++) {
      lhs[i + j] += lhsTmp[i] * rhs[j];
    }
  }
  return lhs;
}

template <typename T> Polynomial<T> operator+(Polynomial<T> poly) {
  auto res = poly;
  return res;
}

template <typename T> Polynomial<T> operator-(Polynomial<T> poly) {
  auto res = poly;
  for (int i = 0; i <= poly.degree(); i++)
    res[i] = -res[i];
  return res;
}

template <typename T> T Polynomial<T>::operator()(T x) {
  T res = T(0);
  T px = T(1);
  for (int i = 0; i <= degree(); i++) {
    res += dat[i] * px;
    px *= x;
  }
  return res;
}

} // namespace ProconLib
using namespace ProconLib;

int powm(int x, int k, int p) {
  int res = 1;
  while (k) {
    if (k & 1)
      res = res * x % p;
    k >>= 1;
    x = x * x % p;
  }
  return res;
}
int inv(int x, int p) { return powm(x, p - 2, p); }
using P = Polynomial<int>;
int main() {
  int p;
  cin >> p;
  vector<int> a(p);
  for (int i = 0; i < p; i++)
    cin >> a[i];

  vector<vector<P>> dp(2, vector<P>(p + 1));
  dp[0][0][0] = 1;
  for (int i = 0; i < p; i++) {
    if (a[i]) {
      int r = 1;
      for (int j = 0; j < p; j++) {
        if (i != j)
          r = r * inv(i - j, p) % p;
      }
      dp[1][i + 1] += dp[0][i];
      for (int j = 0; j <= dp[1][i + 1].degree(); j++)
        dp[1][i + 1][j] *= r;
    }
    P poly(2);
    poly[0] = -i;
    poly[1] = 1;
    dp[0][i + 1] += dp[0][i] * poly;
    dp[1][i + 1] += dp[1][i] * poly;
    for (int j = 0; j <= dp[0][i + 1].degree(); j++)
      dp[0][i + 1][j] %= p;
    for (int j = 0; j <= dp[1][i + 1].degree(); j++)
      dp[1][i + 1][j] %= p;
  }
  for (int i = 0; i + 1 < p; i++) {
    cout << (dp[1][p][i] + p) % p << " ";
  }
  cout << (dp[1][p][p - 1] + p) % p << endl;
  return 0;
}


Fixed submission:
#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <deque>
#include <functional>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <stdexcept>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
using namespace std;
using ll = long long;

#include <algorithm>
#include <vector>
namespace ProconLib {

namespace DetailNS {
template <typename T> struct DefaultDetail {
  static bool isZero(T x) { return x <= T(0); }
};
} // namespace DetailNS
template <typename T> class Polynomial {
  int N;
  std::vector<T> dat;

public:
  Polynomial(int N) : N(N), dat(N + 1) {}
  Polynomial() : Polynomial(0) {}
  Polynomial(const Polynomial &obj) : N(obj.N), dat(obj.dat) {}
  Polynomial(const Polynomial &&obj) : N(obj.N), dat(std::move(obj.dat)) {}

  int degree() { return N; }
  void resize(int N) {
    this->N = N;
    dat.resize(N + 1, T(0));
  }
  template <typename Detail = DetailNS::DefaultDetail<T>> void shrink();
  T &operator[](int pos) { return dat[pos]; }
  const T &operator[](int pos) const { return dat[pos]; }

  T operator()(T x);
};

template <typename T>
Polynomial<T> &operator+=(Polynomial<T> &lhs, Polynomial<T> rhs);
template <typename T>
Polynomial<T> &operator-=(Polynomial<T> &lhs, Polynomial<T> rhs);
template <typename T>
Polynomial<T> &operator*=(Polynomial<T> &lhs, Polynomial<T> rhs);
template <typename T>
Polynomial<T> operator+(Polynomial<T> lhs, Polynomial<T> rhs) {
  return lhs += rhs;
}
template <typename T>
Polynomial<T> operator-(Polynomial<T> lhs, Polynomial<T> rhs) {
  return lhs -= rhs;
}
template <typename T>
Polynomial<T> operator*(Polynomial<T> lhs, Polynomial<T> rhs) {
  return lhs *= rhs;
}

template <typename T> template <typename Detail> void Polynomial<T>::shrink() {
  while (N) {
    if (Detail::isZero(dat[N]))
      N--;
    else
      break;
  }
  resize(N);
}

template <typename T>
Polynomial<T> &operator+=(Polynomial<T> &lhs, Polynomial<T> rhs) {
  lhs.resize(std::max(lhs.degree(), rhs.degree()));
  for (int i = 0; i <= rhs.degree(); i++)
    lhs[i] += rhs[i];
  return lhs;
}

template <typename T>
Polynomial<T> &operator-=(Polynomial<T> &lhs, Polynomial<T> rhs) {
  lhs.resize(std::max(lhs.degree(), rhs.degree()));
  for (int i = 0; i <= rhs.degree(); i++)
    lhs[i] -= rhs[i];
  return lhs;
}

template <typename T>
Polynomial<T> &operator*=(Polynomial<T> &lhs, Polynomial<T> rhs) {
  Polynomial<T> lhsTmp = lhs;
  lhs.resize(lhs.degree() + rhs.degree());
  for (int i = 0; i <= lhsTmp.degree(); i++)
    lhs[i] = T(0);
  for (int i = 0; i <= lhsTmp.degree(); i++) {
    for (int j = 0; j <= rhs.degree(); j++) {
      lhs[i + j] += lhsTmp[i] * rhs[j];
    }
  }
  return lhs;
}

template <typename T> Polynomial<T> operator+(Polynomial<T> poly) {
  auto res = poly;
  return res;
}

template <typename T> Polynomial<T> operator-(Polynomial<T> poly) {
  auto res = poly;
  for (int i = 0; i <= poly.degree(); i++)
    res[i] = -res[i];
  return res;
}

template <typename T> T Polynomial<T>::operator()(T x) {
  T res = T(0);
  T px = T(1);
  for (int i = 0; i <= degree(); i++) {
    res += dat[i] * px;
    px *= x;
  }
  return res;
}

} // namespace ProconLib
using namespace ProconLib;

int powm(int x, int k, int p) {
  int res = 1;
  while (k) {
    if (k & 1)
      res = res * x % p;
    k >>= 1;
    x = x * x % p;
  }
  return res;
}
int inv(int x, int p) { return powm(x, p - 2, p); }
using P = Polynomial<int>;
int main() {
  int p;
  cin >> p;
  vector<int> a(p);
  for (int i = 0; i < p; i++)
    cin >> a[i];

  vector<vector<P>> dp(2, vector<P>(p + 1));
  dp[0][0][0] = 1;
  for (int i = 0; i < p; i++) {
    if (a[i]) {
      int r = 1;
      for (int j = 0; j < p; j++) {
        if (i != j)
          r = r * inv(i - j, p) % p;
      }
      dp[1][i + 1] += dp[0][i];
      for (int j = 0; j <= dp[1][i + 1].degree(); j++)
        dp[1][i + 1][j] *= r;
    }
    P poly(2);
    poly[0] = -i;
    poly[1] = 1;
    dp[0][i + 1] += dp[0][i] * poly;
    dp[1][i + 1] += dp[1][i] * poly;
    for (int j = 0; j <= dp[0][i + 1].degree(); j++)
      dp[0][i + 1][j] %= p;
    for (int j = 0; j <= dp[1][i + 1].degree(); j++)
      dp[1][i + 1][j] %= p;
  }
  for (int i = 0; i + 1 < p; i++) {
    cout << (dp[1][p][i] + p) % p << " ";
  }
  cout << (dp[1][p][p - 1] + p) % p << endl;
  return 0;
}