Problem:
Score : 600 points

Problem Statement

Given are a prime number p and a sequence of p integers a_0, \ldots, a_{p-1} consisting of zeros and ones.

Find a polynomial of degree at most p-1, f(x) = b_{p-1} x^{p-1} + b_{p-2} x^{p-2} + \ldots + b_0, satisfying the following conditions:

For each i (0 \leq i \leq p-1), b_i is an integer such that 0 \leq b_i \leq p-1.

For each i (0 \leq i \leq p-1), f(i) \equiv a_i \pmod p.

Constraints

2 \leq p \leq 2999

p is a prime number.

0 \leq a_i \leq 1

Input

Input is given from Standard Input in the following format:

p
a_0 a_1 \ldots a_{p-1}

Output

Print b_0, b_1, \ldots, b_{p-1} of a polynomial f(x) satisfying the conditions, in this order, with spaces in between.

It can be proved that a solution always exists. If multiple solutions exist, any of them will be accepted.

Sample Input 1

2
1 0

Sample Output 1

1 1

f(x) = x + 1 satisfies the conditions, as follows:

f(0) = 0 + 1 = 1 \equiv 1 \pmod 2

f(1) = 1 + 1 = 2 \equiv 0 \pmod 2

Sample Input 2

3
0 0 0

Sample Output 2

0 0 0

f(x) = 0 is also valid.

Sample Input 3

5
0 1 0 1 0

Sample Output 3

0 2 0 1 3

Solution in C++14 (GCC 5.4.1) (judge verdict: Time Limit Exceeded)

#include <bits/stdc++.h>
#define rep(i, n) for(int i = 0; i < (n); i++)
#define int long long
#define double long double
#define all(a) a.begin(), a.end()
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
using namespace std;

int mod;
struct mint{ //modint
    int x;
    mint(int x = 0): x((x % mod + mod) % mod) {}
    friend istream& operator >> (istream &s, mint& m){ return s >> m.x; }
    friend ostream& operator << (ostream &s, mint m){ return s << m.x; }
    inline mint& operator += (mint a){ if((x += a.x) >= mod)x -= mod; return *this; }
    inline mint& operator -= (mint a){ if((x += mod - a.x) >= mod)x -= mod; return *this; }
    inline mint& operator *= (mint a){ (x *= a.x) %= mod; return *this; }
    inline mint& operator /= (mint a){ return (*this) *= a.inv(); }
    inline mint operator + (mint a){ mint res(*this); return res += a; }
    inline mint operator - (mint a){ mint res(*this); return res -= a; }
    inline mint operator * (mint a){ mint res(*this); return res *= a; }
    inline mint operator / (mint a){ mint res(*this); return res /= a; }
    inline bool operator == (mint a){ return x == a.x; }
    inline bool operator != (mint a){ return x != a.x; }
    inline bool operator < (mint a){ return x < a.x; }
    inline bool operator > (mint a){ return x > a.x; }
    inline bool operator <= (mint a){ return x <= a.x; }
    inline bool operator >= (mint a){ return x >= a.x; }
    inline void takemod(){ x = ((x % mod) + mod) % mod; }
    mint inv(){ return pow(mod - 2); }
    mint pow(int p){
        mint res(1), tmp(x);
        for(; p; p >>= 1){ if(p & 1)res *= tmp; tmp *= tmp; }
        return res;
    }
};

struct mfact{ //modfact
    vector<mint> fact, ifact;
    mfact(int size = 200010) : fact(size + 1), ifact(size + 1) {
        fact[0] = 1;
        for(int i = 1; i <= size; i++)fact[i] = fact[i - 1] * mint(i);
        ifact[size] = fact[size].inv();
        for(int i = size; i > 0; i--)ifact[i - 1] = ifact[i] * mint(i);
    }
    inline mint operator [] (int i){ return fact[i]; }
    inline mint nPr(int n, int r){ return fact[n] * ifact[r]; }
    inline mint nCr(int n, int r){ return fact[n] / (fact[n - r] * fact[r]); }
};

//ABC137
signed main(void){

    int P; cin >> P; mod = P;
    vector<mint> ans(P, mint(0));
    mfact fact(P);

    rep(i, P){
        int a; cin >> a;
        if(a == 1){
            // f(x) に (1 - (x - i) ^ (p - 1)) を足す-
            ans[0] += 1;
            mint now(1);
            for(int j = P - 1; j >= 0; j--){
                ans[j] -= now * fact.nCr(P - 1, j);
                now *= mint(-i);
            }
        }
    }

    rep(i, P){
        if(i)cout << ' ';
        cout << ans[i];
    }
    cout << endl;
    return 0;

}