Problem p02950 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>

using namespace std;
using ll = long long;
// #define int ll
using PII = pair<ll, ll>;

#define FOR(i, a, n) for (ll i = (ll)a; i < (ll)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define ALL(x) x.begin(), x.end()

template <typename T> T &chmin(T &a, const T &b) { return a = min(a, b); }
template <typename T> T &chmax(T &a, const T &b) { return a = max(a, b); }
template <typename T> bool IN(T a, T b, T x) { return a <= x && x < b; }
template <typename T> T ceil(T a, T b) { return a / b + !!(a % b); }

template <typename T> vector<T> make_v(size_t a) { return vector<T>(a); }
template <typename T, typename... Ts> auto make_v(size_t a, Ts... ts) {
  return vector<decltype(make_v<T>(ts...))>(a, make_v<T>(ts...));
}
template <typename T, typename V>
typename enable_if<is_class<T>::value == 0>::type fill_v(T &t, const V &v) {
  t = v;
}
template <typename T, typename V>
typename enable_if<is_class<T>::value != 0>::type fill_v(T &t, const V &v) {
  for (auto &e : t)
    fill_v(e, v);
}

template <class S, class T>
ostream &operator<<(ostream &out, const pair<S, T> &a) {
  out << '(' << a.first << ',' << a.second << ')';
  return out;
}
template <class T> ostream &operator<<(ostream &out, const vector<T> &a) {
  out << '[';
  for (const T &i : a)
    out << i << ',';
  out << ']';
  return out;
}
template <class T> ostream &operator<<(ostream &out, const set<T> &a) {
  out << '{';
  for (const T &i : a)
    out << i << ',';
  out << '}';
  return out;
}
template <class T, class S>
ostream &operator<<(ostream &out, const map<T, S> &a) {
  out << '{';
  for (auto &i : a)
    out << i << ',';
  out << '}';
  return out;
}

int dx[] = {0, 1, 0, -1}, dy[] = {1, 0, -1, 0}; // DRUL
const int INF = 1 << 30;
const ll LLINF = 1LL << 60;

// 実行時にmodを決定するmodint
ll MOD;
struct mint {
  ll x;
  mint() : x(0) {}
  mint(ll y) : x(y >= 0 ? y % MOD : y % MOD + MOD) {}
  // e乗
  friend mint pow(mint p, ll e) {
    mint a(1);
    while (e > 0) {
      if (e % 2 == 0) {
        p = (p * p);
        e /= 2;
      } else {
        a = (a * p);
        e--;
      }
    }
    return a;
  }
  mint inv() const {
    ll a = x, b = MOD, u = 1, y = 1, v = 0, z = 0;
    while (a) {
      ll q = b / a;
      swap(z -= q * u, u);
      swap(y -= q * v, v);
      swap(b -= q * a, a);
    }
    return z;
  }
  // Comparators
  bool operator!=(mint b) { return x != b.x; }
  bool operator==(mint b) { return x == b.x; }
  // Basic Operations
  mint operator+(mint r) const { return mint(*this) += r; }
  mint operator-(mint r) const { return mint(*this) -= r; }
  mint operator*(mint r) const { return mint(*this) *= r; }
  mint operator/(mint r) const { return mint(*this) /= r; }
  mint &operator+=(mint r) {
    if ((x += r.x) >= MOD)
      x -= MOD;
    return *this;
  }
  mint &operator-=(mint r) {
    if ((x -= r.x) < 0)
      x += MOD;
    return *this;
  }
  mint &operator*=(mint r) {
#if !defined(_WIN32) || defined(_WIN64)
    x = x * r.x % MOD;
    return *this;
#endif
    unsigned long long y = x * r.x;
    unsigned xh = (unsigned)(y >> 32), xl = (unsigned)y, d, m;
    asm("divl %4; \n\t" : "=a"(d), "=d"(m) : "d"(xh), "a"(xl), "r"(MOD));
    x = m;
    return *this;
  }
  mint &operator/=(mint r) { return *this *= r.inv(); }
  template <class T> friend mint operator*(T l, mint r) { return mint(l) *= r; }
  template <class T> friend mint operator+(T l, mint r) { return mint(l) += r; }
  template <class T> friend mint operator-(T l, mint r) { return mint(l) -= r; }
  template <class T> friend mint operator/(T l, mint r) { return mint(l) /= r; }
  template <class T> friend bool operator==(T l, mint r) {
    return mint(l) == r;
  }
  template <class T> friend bool operator!=(T l, mint r) {
    return mint(l) != r;
  }
  // increment, decrement
  mint operator++() {
    x++;
    return *this;
  }
  mint operator++(signed) {
    mint t = *this;
    x++;
    return t;
  }
  mint operator--() {
    x--;
    return *this;
  }
  mint operator--(signed) {
    mint t = *this;
    x--;
    return t;
  }
  // Input/Output
  friend ostream &operator<<(ostream &os, mint a) { return os << a.x; }
  friend istream &operator>>(istream &is, mint &a) { return is >> a.x; }
  friend string to_frac(mint v) {
    static map<ll, PII> mp;
    if (mp.empty()) {
      mp[0] = mp[MOD] = {0, 1};
      FOR(i, 2, 1001) FOR(j, 1, i) if (__gcd(i, j) == 1) {
        mp[(mint(i) / j).x] = {i, j};
      }
    }
    auto itr = mp.lower_bound(v.x);
    if (itr != mp.begin() && v.x - prev(itr)->first < itr->first - v.x)
      --itr;
    string ret = to_string(itr->second.first +
                           itr->second.second * ((int)v.x - itr->first));
    if (itr->second.second > 1) {
      ret += '/';
      ret += to_string(itr->second.second);
    }
    return ret;
  }
};

// x座標が相異なるn+1点(x_i,y_i)を通るn次以下の多項式f(x)を返す
// O(n^2)
vector<mint> lagrange_interpolation(vector<mint> x, vector<mint> y) {
  const ll n = x.size() - 1;
  REP(i, n + 1) REP(j, n + 1) if (i != j) y[i] /= x[i] - x[j];
  vector<vector<mint>> dp(n + 1, vector<mint>(n + 2));
  dp[0][0] = -1 * x[0], dp[0][1] = 1;
  FOR(i, 1, n + 1) REP(j, n + 2) {
    dp[i][j] = dp[i - 1][j] * -1 * x[i];
    if (j >= 1)
      dp[i][j] += dp[i - 1][j - 1];
  }
  vector<mint> xinv(n + 1);
  REP(i, n + 1) xinv[i] = x[i].inv();
  vector<mint> ret(n + 1); // f(x)
  REP(i, n + 1) {
    if (y[i] == 0)
      continue;
    // 0割り対策の場合分け
    if (x[i] == 0) {
      REP(j, n + 1) ret[j] += dp[n][j + 1] * y[i];
    } else {
      ret[0] -= dp[n][0] * xinv[i] * y[i];
      mint pre = -1 * dp[n][0] * xinv[i];
      FOR(j, 1, n + 1) {
        ret[j] -= (dp[n][j] - pre) * xinv[i] * y[i];
        pre = -1 * (dp[n][j] - pre) * xinv[i];
      }
    }
  }
  return ret;
}

signed main(void) {
  cin.tie(0);
  ios::sync_with_stdio(false);

  ll p;
  cin >> p;
  MOD = p;
  vector<mint> y(p);
  REP(i, p) cin >> y[i];

  vector<mint> x(p);
  REP(i, p) x[i] = i;
  auto ret = lagrange_interpolation(x, y);
  REP(i, p) cout << ret[i] << (i == p - 1 ? '\n' : ' ');

  return 0;
}


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

using namespace std;
using ll = long long;
// #define int ll
using PII = pair<ll, ll>;

#define FOR(i, a, n) for (ll i = (ll)a; i < (ll)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define ALL(x) x.begin(), x.end()

template <typename T> T &chmin(T &a, const T &b) { return a = min(a, b); }
template <typename T> T &chmax(T &a, const T &b) { return a = max(a, b); }
template <typename T> bool IN(T a, T b, T x) { return a <= x && x < b; }
template <typename T> T ceil(T a, T b) { return a / b + !!(a % b); }

template <typename T> vector<T> make_v(size_t a) { return vector<T>(a); }
template <typename T, typename... Ts> auto make_v(size_t a, Ts... ts) {
  return vector<decltype(make_v<T>(ts...))>(a, make_v<T>(ts...));
}
template <typename T, typename V>
typename enable_if<is_class<T>::value == 0>::type fill_v(T &t, const V &v) {
  t = v;
}
template <typename T, typename V>
typename enable_if<is_class<T>::value != 0>::type fill_v(T &t, const V &v) {
  for (auto &e : t)
    fill_v(e, v);
}

template <class S, class T>
ostream &operator<<(ostream &out, const pair<S, T> &a) {
  out << '(' << a.first << ',' << a.second << ')';
  return out;
}
template <class T> ostream &operator<<(ostream &out, const vector<T> &a) {
  out << '[';
  for (const T &i : a)
    out << i << ',';
  out << ']';
  return out;
}
template <class T> ostream &operator<<(ostream &out, const set<T> &a) {
  out << '{';
  for (const T &i : a)
    out << i << ',';
  out << '}';
  return out;
}
template <class T, class S>
ostream &operator<<(ostream &out, const map<T, S> &a) {
  out << '{';
  for (auto &i : a)
    out << i << ',';
  out << '}';
  return out;
}

int dx[] = {0, 1, 0, -1}, dy[] = {1, 0, -1, 0}; // DRUL
const int INF = 1 << 30;
const ll LLINF = 1LL << 60;

// 実行時にmodを決定するmodint
ll MOD;
struct mint {
  ll x;
  mint() : x(0) {}
  mint(ll y) : x(y >= 0 ? y % MOD : y % MOD + MOD) {}
  // e乗
  friend mint pow(mint p, ll e) {
    mint a(1);
    while (e > 0) {
      if (e % 2 == 0) {
        p = (p * p);
        e /= 2;
      } else {
        a = (a * p);
        e--;
      }
    }
    return a;
  }
  mint inv() const {
    ll a = x, b = MOD, u = 1, y = 1, v = 0, z = 0;
    while (a) {
      ll q = b / a;
      swap(z -= q * u, u);
      swap(y -= q * v, v);
      swap(b -= q * a, a);
    }
    return z;
  }
  // Comparators
  bool operator!=(mint b) { return x != b.x; }
  bool operator==(mint b) { return x == b.x; }
  // Basic Operations
  mint operator+(mint r) const { return mint(*this) += r; }
  mint operator-(mint r) const { return mint(*this) -= r; }
  mint operator*(mint r) const { return mint(*this) *= r; }
  mint operator/(mint r) const { return mint(*this) /= r; }
  mint &operator+=(mint r) {
    if ((x += r.x) >= MOD)
      x -= MOD;
    return *this;
  }
  mint &operator-=(mint r) {
    if ((x -= r.x) < 0)
      x += MOD;
    return *this;
  }
  mint &operator*=(mint r) {
#if !defined(_WIN32) || defined(_WIN64)
    x = x * r.x % MOD;
    return *this;
#endif
    unsigned long long y = x * r.x;
    unsigned xh = (unsigned)(y >> 32), xl = (unsigned)y, d, m;
    asm("divl %4; \n\t" : "=a"(d), "=d"(m) : "d"(xh), "a"(xl), "r"(MOD));
    x = m;
    return *this;
  }
  mint &operator/=(mint r) { return *this *= r.inv(); }
  template <class T> friend mint operator*(T l, mint r) { return mint(l) *= r; }
  template <class T> friend mint operator+(T l, mint r) { return mint(l) += r; }
  template <class T> friend mint operator-(T l, mint r) { return mint(l) -= r; }
  template <class T> friend mint operator/(T l, mint r) { return mint(l) /= r; }
  template <class T> friend bool operator==(T l, mint r) {
    return mint(l) == r;
  }
  template <class T> friend bool operator!=(T l, mint r) {
    return mint(l) != r;
  }
  // increment, decrement
  mint operator++() {
    x++;
    return *this;
  }
  mint operator++(signed) {
    mint t = *this;
    x++;
    return t;
  }
  mint operator--() {
    x--;
    return *this;
  }
  mint operator--(signed) {
    mint t = *this;
    x--;
    return t;
  }
  // Input/Output
  friend ostream &operator<<(ostream &os, mint a) { return os << a.x; }
  friend istream &operator>>(istream &is, mint &a) { return is >> a.x; }
  friend string to_frac(mint v) {
    static map<ll, PII> mp;
    if (mp.empty()) {
      mp[0] = mp[MOD] = {0, 1};
      FOR(i, 2, 1001) FOR(j, 1, i) if (__gcd(i, j) == 1) {
        mp[(mint(i) / j).x] = {i, j};
      }
    }
    auto itr = mp.lower_bound(v.x);
    if (itr != mp.begin() && v.x - prev(itr)->first < itr->first - v.x)
      --itr;
    string ret = to_string(itr->second.first +
                           itr->second.second * ((int)v.x - itr->first));
    if (itr->second.second > 1) {
      ret += '/';
      ret += to_string(itr->second.second);
    }
    return ret;
  }
};

// x座標が相異なるn+1点(x_i,y_i)を通るn次以下の多項式f(x)を返す
// O(n^2)
vector<mint> lagrange_interpolation(vector<mint> x, vector<mint> y) {
  const ll n = x.size() - 1;
  REP(i, n + 1) {
    mint t = 1;
    REP(j, n + 1) if (i != j) t *= x[i] - x[j];
    y[i] /= t;
  }
  vector<vector<mint>> dp(n + 1, vector<mint>(n + 2));
  dp[0][0] = -1 * x[0], dp[0][1] = 1;
  FOR(i, 1, n + 1) REP(j, n + 2) {
    dp[i][j] = dp[i - 1][j] * -1 * x[i];
    if (j >= 1)
      dp[i][j] += dp[i - 1][j - 1];
  }
  vector<mint> xinv(n + 1);
  REP(i, n + 1) xinv[i] = x[i].inv();
  vector<mint> ret(n + 1); // f(x)
  REP(i, n + 1) {
    if (y[i] == 0)
      continue;
    // 0割り対策の場合分け
    if (x[i] == 0) {
      REP(j, n + 1) ret[j] += dp[n][j + 1] * y[i];
    } else {
      ret[0] -= dp[n][0] * xinv[i] * y[i];
      mint pre = -1 * dp[n][0] * xinv[i];
      FOR(j, 1, n + 1) {
        ret[j] -= (dp[n][j] - pre) * xinv[i] * y[i];
        pre = -1 * (dp[n][j] - pre) * xinv[i];
      }
    }
  }
  return ret;
}

signed main(void) {
  cin.tie(0);
  ios::sync_with_stdio(false);

  ll p;
  cin >> p;
  MOD = p;
  vector<mint> y(p);
  REP(i, p) cin >> y[i];

  vector<mint> x(p);
  REP(i, p) x[i] = i;
  auto ret = lagrange_interpolation(x, y);
  REP(i, p) cout << ret[i] << (i == p - 1 ? '\n' : ' ');

  return 0;
}