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: Accepted)

#include <bits/stdc++.h>
using namespace std;

#define N 3005

int mod;

int inv[N];

struct poly {
    vector <int> A;
    poly(int n=1,int m=0) {
		resize(n);
		fill(A.begin(),A.end(),m);
	}
	int size() {return A.size();}
	void resize(int n) {A.resize(n);}
	int & operator [](int i) {return A[i];}
    void trim() {
        while (!A.empty() && A.back() == 0) A.pop_back();
        if (A.empty()) A.push_back(0);
    }
    poly operator * (poly &B) {
        int sz = A.size() + B.size() - 1;
        poly C(sz, 0);
        for (int i = 0; i < A.size(); i ++) {
            for (int j = 0; j < B.size(); j ++) {
				C[i+j] = (C[i+j] + 1ll * A[i] * B[j]) % mod;
            }
        }
        C.trim();
        return C;
    }
    poly operator - (poly B) {
        int sz = max((int)A.size(), B.size());
        poly C(sz, 0);
        for (int i = 0; i < sz; i ++) {
            if (i < A.size()) {
                C[i] += A[i];
                if (C[i] >= mod) C[i] -= mod;
            }
            if (i < B.size()) {
                C[i] -= B[i];
                if (C[i] < 0) C[i] += mod;
            }
        }
        C.trim();
        return C;
	}
    poly operator / (poly &B) {
        int n = A.size() - 1, m = B.size() - 1;
        if (n < m) return poly(1, 0);
        int sz = n - m + 1;
        poly C(sz, 0);
        poly tmp; tmp.A = A;
        int coe = inv[B[m]];
        for (int i = n; i >= m; i --) {
            int k = 1ll * tmp[i] * coe % mod;
            C[i-m] = k;
            for (int j = m; j >= 0; j --) {
                tmp[i-m+j] = (tmp[i-m+j] - 1ll * B[j] * k) % mod;
                if (tmp[i-m+j] < 0) tmp[i-m+j] += mod;
            }
        }
        C.trim();
        return C;
    }
    void print() {
		for (int i = 0; i < A.size(); i ++) printf("%d ", A[i]);
		puts("");
    }
} A(1, 1), B(1, 1);

poly extended_euclid(poly a, poly b, poly &x, poly &y) {
    if (b.size() == 1 && b[0] == 0) {
        x = poly(1, 1), y = poly(1, 0);
        return a;
    }
    poly D = a / b;
    poly rlt = extended_euclid(b, a - D * b, y, x);
    y = y - D * x;
    return rlt;
}

int a[N];

int main() {
//	freopen("1.in", "r", stdin);
	int p;
    scanf("%d", &p);
    inv[1] = 1;
    for (int i = 2; i < p; i ++) inv[i] = 1ll * (p / i) * (p - inv[p%i]) % p;
    mod = p;
    for (int i = 0; i < p; i ++) {
		scanf("%d", &a[i]);
        if (a[i] == 0) {
            poly tmp(2, 0);
            tmp[0] = (p - i) % p;
            tmp[1] = 1;
            A = A * tmp;
        }
        else {
            poly tmp(2, 0);
            tmp[0] = (p - i) % p;
            tmp[1] = 1;
            B = B * tmp;
        }
    }
    poly X, Y;
    poly C = extended_euclid(A, B, X, Y);
    A = A * X;
    int d = inv[C[0]];
    for (int i = 0; i < A.size(); i ++) printf("%d ", A[i] * d % mod);
    for (int i = A.size(); i < p; i ++) printf("0 ");
    puts("");
    return 0;
}