Problem p02950 (C++)

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

using namespace std;
using ll = long long;

ll mod;

struct Modint {
  ll num;
  Modint() : num() { num = 0; }
  Modint(ll x) : num() {
    num = x % mod;
    if (num < 0)
      num += mod;
  }
  inline Modint &operator=(int x) {
    num = x % mod;
    if (num < 0)
      num += mod;
    return *this;
  }
  inline Modint &operator=(ll x) {
    num = x % mod;
    if (num < 0)
      num += mod;
    return *this;
  }
  inline Modint &operator=(Modint x) {
    num = x.num;
    return *this;
  }
  inline Modint operator+(int x) const { return Modint(num + x); }
  inline Modint operator+(ll x) const { return Modint(num + x); }
  inline Modint operator+(Modint x) const {
    ll a = num + x.num;
    if (a >= mod)
      a -= mod;
    return Modint{a};
  }
  inline Modint &operator+=(int x) {
    num += x;
    num %= mod;
    if (num < 0)
      num += mod;
    return *this;
  }
  inline Modint &operator+=(ll x) {
    num += x;
    num %= mod;
    if (num < 0)
      num += mod;
    return *this;
  }
  inline Modint &operator+=(Modint x) {
    num += x.num;
    if (num >= mod)
      num -= mod;
    return *this;
  }
  inline Modint &operator++() {
    if (num == mod - 1)
      num = 0;
    else
      num++;
    return *this;
  }
  inline Modint operator++(int) {
    Modint ans = *this;
    if (num == mod - 1)
      num = 0;
    else
      num++;
    return ans;
  }
  inline Modint operator-() const {
    if (num == 0)
      return 0;
    return Modint(mod - num);
  }
  inline Modint operator-(int x) const { return Modint(num - x); }
  inline Modint operator-(ll x) const { return Modint(num - x); }
  inline Modint operator-(Modint x) const {
    ll a = num - x.num;
    if (a < 0)
      a += mod;
    return Modint{a};
  }
  inline Modint &operator-=(int x) {
    num -= x;
    num %= mod;
    if (num < 0)
      num += mod;
    return *this;
  }
  inline Modint &operator-=(ll x) {
    num -= x;
    num %= mod;
    if (num < 0)
      num += mod;
    return *this;
  }
  inline Modint &operator-=(Modint x) {
    num -= x.num;
    if (num < 0)
      num += mod;
    return *this;
  }
  inline Modint &operator--() {
    if (num == 0)
      num = mod - 1;
    else
      num--;
    return *this;
  }
  inline Modint operator--(int) {
    Modint ans = *this;
    if (num == 0)
      num = mod - 1;
    else
      num--;
    return ans;
  }
  inline Modint operator*(int x) const { return Modint(num * (x % mod)); }
  inline Modint operator*(ll x) const { return Modint(num * (x % mod)); }
  inline Modint operator*(Modint x) const { return Modint{num * x.num % mod}; }
  inline Modint &operator*=(int x) {
    num *= Modint(x);
    num %= mod;
    return *this;
  }
  inline Modint &operator*=(ll x) {
    num *= Modint(x);
    num %= mod;
    return *this;
  }
  inline Modint &operator*=(Modint x) {
    num *= x.num;
    num %= mod;
    return *this;
  }
  inline Modint pow(ll x) const {
    ll i = 1;
    Modint ans = 1, cnt = *this;
    while (i <= x) {
      if (x & i) {
        ans *= cnt;
        x ^= i;
      }
      cnt *= cnt;
      i *= 2;
    }
    return ans;
  }
  inline operator ll() const { return num; }
};

// 階乗、階乗の逆元、逆元
const int MAX = 3000;
Modint fact[MAX], finv[MAX], inv[MAX];

// 階乗、逆元の前処理
void Cinit(ll mod) {
  fact[0] = fact[1] = 1;
  finv[0] = finv[1] = 1;
  inv[1] = 1;
  for (int i = 2; i < MAX; i++) {
    fact[i] = fact[i - 1] * i;
    inv[i] = -(inv[mod % i] * (mod / i));
    finv[i] = finv[i - 1] * inv[i];
  }
}

// combination
Modint nCk(ll n, ll k) {
  if (n < k)
    return 0;
  if (n < 0 || k < 0)
    return 0;
  return fact[n] * (finv[k] * finv[n - k]);
}

int main() {
  ll p;
  cin >> p;
  mod = p;
  vector<ll> a(p);
  vector<Modint> ret(p, 0);
  for (int i = 0; i < p; ++i) {
    cin >> a[i];
    if (a[i] == 1)
      ret[0]++;
  }
  Cinit(p);
  for (int i = 0; i < p; ++i) {
    if (a[i] != 1)
      continue;
    for (int j = 0; j < p; ++j) {
      ret[j] += nCk(p - 1, j) * (-Modint(-i).pow(p - 1 - j));
    }
  }

  for (int i = 0; i < p; ++i) {
    cout << ret[i] << " ";
  }
}


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

using namespace std;
using ll = long long;

ll mod;

struct Modint {
  ll num;
  Modint() : num() { num = 0; }
  Modint(ll x) : num() {
    num = x % mod;
    if (num < 0)
      num += mod;
  }
  inline Modint &operator=(int x) {
    num = x % mod;
    if (num < 0)
      num += mod;
    return *this;
  }
  inline Modint &operator=(ll x) {
    num = x % mod;
    if (num < 0)
      num += mod;
    return *this;
  }
  inline Modint &operator=(Modint x) {
    num = x.num;
    return *this;
  }
  inline Modint operator+(int x) const { return Modint(num + x); }
  inline Modint operator+(ll x) const { return Modint(num + x); }
  inline Modint operator+(Modint x) const {
    ll a = num + x.num;
    if (a >= mod)
      a -= mod;
    return Modint{a};
  }
  inline Modint &operator+=(int x) {
    num += x;
    num %= mod;
    if (num < 0)
      num += mod;
    return *this;
  }
  inline Modint &operator+=(ll x) {
    num += x;
    num %= mod;
    if (num < 0)
      num += mod;
    return *this;
  }
  inline Modint &operator+=(Modint x) {
    num += x.num;
    if (num >= mod)
      num -= mod;
    return *this;
  }
  inline Modint &operator++() {
    if (num == mod - 1)
      num = 0;
    else
      num++;
    return *this;
  }
  inline Modint operator++(int) {
    Modint ans = *this;
    if (num == mod - 1)
      num = 0;
    else
      num++;
    return ans;
  }
  inline Modint operator-() const {
    if (num == 0)
      return 0;
    return Modint(mod - num);
  }
  inline Modint operator-(int x) const { return Modint(num - x); }
  inline Modint operator-(ll x) const { return Modint(num - x); }
  inline Modint operator-(Modint x) const {
    ll a = num - x.num;
    if (a < 0)
      a += mod;
    return Modint{a};
  }
  inline Modint &operator-=(int x) {
    num -= x;
    num %= mod;
    if (num < 0)
      num += mod;
    return *this;
  }
  inline Modint &operator-=(ll x) {
    num -= x;
    num %= mod;
    if (num < 0)
      num += mod;
    return *this;
  }
  inline Modint &operator-=(Modint x) {
    num -= x.num;
    if (num < 0)
      num += mod;
    return *this;
  }
  inline Modint &operator--() {
    if (num == 0)
      num = mod - 1;
    else
      num--;
    return *this;
  }
  inline Modint operator--(int) {
    Modint ans = *this;
    if (num == 0)
      num = mod - 1;
    else
      num--;
    return ans;
  }
  inline Modint operator*(int x) const { return Modint(num * (x % mod)); }
  inline Modint operator*(ll x) const { return Modint(num * (x % mod)); }
  inline Modint operator*(Modint x) const { return Modint{num * x.num % mod}; }
  inline Modint &operator*=(int x) {
    num *= Modint(x);
    num %= mod;
    return *this;
  }
  inline Modint &operator*=(ll x) {
    num *= Modint(x);
    num %= mod;
    return *this;
  }
  inline Modint &operator*=(Modint x) {
    num *= x.num;
    num %= mod;
    return *this;
  }
  inline Modint pow(ll x) const {
    ll i = 1;
    Modint ans = 1, cnt = *this;
    while (i <= x) {
      if (x & i) {
        ans *= cnt;
        x ^= i;
      }
      cnt *= cnt;
      i *= 2;
    }
    return ans;
  }
  inline operator ll() const { return num; }
};

// 階乗、階乗の逆元、逆元
const int MAX = 3000;
Modint fact[MAX], finv[MAX], inv[MAX];

// 階乗、逆元の前処理
void Cinit(ll mod) {
  fact[0] = fact[1] = 1;
  finv[0] = finv[1] = 1;
  inv[1] = 1;
  for (int i = 2; i < MAX; i++) {
    fact[i] = fact[i - 1] * i;
    inv[i] = -(inv[mod % i] * (mod / i));
    finv[i] = finv[i - 1] * inv[i];
  }
}

// combination
Modint nCk(ll n, ll k) {
  if (n < k)
    return 0;
  if (n < 0 || k < 0)
    return 0;
  return fact[n] * (finv[k] * finv[n - k]);
}

int main() {
  ll p;
  cin >> p;
  mod = p;
  vector<ll> a(p);
  vector<Modint> ret(p, 0);
  for (int i = 0; i < p; ++i) {
    cin >> a[i];
    if (a[i] == 1)
      ret[0]++;
  }
  Cinit(p);
  for (int i = 0; i < p; ++i) {
    if (a[i] != 1)
      continue;
    Modint c(1);
    for (int j = p - 1; j >= 0; --j) {
      ret[j] -= nCk(p - 1, j) * c;
      c *= -i;
    }
  }

  for (int i = 0; i < p; ++i) {
    cout << ret[i] << " ";
  }
}