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;
typedef long long ll;



int p;

// x / y 
int mdiv( int x, int y ){
	int exp = p - 2;
	while ( exp ){
		if ( exp % 2 )
			x = (x * y) % p;
		y = (y * y) % p;
		exp /= 2;
	}
	return x;
}



/*
  g(x) = x(x-1)(x-2)(x-3)....(x-(p-1)) の多項式を作成する。
  gi(x) = g(x)/(x-i)
  
  result(x) = 0
  for ( i )
    if ( ai == 1 )
       result(x) += gi(x)/gi(i)
  
*/

// g(x) を出力する
void test( vector<int> &g, string label ){
	cout << label << " is ";
	for ( auto it : g ){
		cout << (it%p) << " ";
	}
	cout << endl;
	cout << "f(x) is ";
	for ( int x = 0; x < p; x++ ){
		int sum = 0;
		int mul = 1;
		for ( auto it : g ){
			sum = (sum + (it%p) * mul)%p;
			mul = (mul * x) % p;
		}
		cout << (sum%p) << " ";
	}
	cout << endl;
	cout << endl;
}




int main(){
	cin >> p;
	
	vector<int> a(p);
	for ( int i = 0; i < p; i++ ){
		cin >> a[i];
	}
	
	vector<int> inv(p);
	for ( int i = 1; i < p; i++ ){
		inv[i] = mdiv(1,i);
	}
	
	vector<int> g(p+1);
	g[0] = 1;
	for ( int i = 0; i < p; i++ ){
		// g に (x-i) を掛ける
		int tmp = 0;
		for ( int j = 0; j <= p; j++ ){
			int tmp2 = g[j];
			g[j] = (g[j] * (p-i) + tmp) % p;
			tmp = tmp2;
		}
	}
	
	//test( g, "g" );
	
	vector<int> result(p);
	for ( int i = 0; i < p; i++ ){
		if ( a[i] ){
			
			// gi = g / (x-i)
			vector<int> gi(p);
			vector<int> gg = g;
			
			for ( int j = p-1; j >= 0; j-- ){
				int c = gi[j] = gg[j+1];
				
				gg[j+1] = 0;
				gg[j] = (gg[j] - (-i*c)) % p;
			}
			
			// gii = gi(i)
			int xp = 1;
			int gii = 0;
			for ( int j = 0; j < p; j++ ){
				gii = (gii + gi[j] * xp) % p;
				xp = (xp * i) % p;
			}
			gii = gii % p;
			
			// result(x) += gi(x)/gii
			for ( int j = 0; j < p; j++ )
				result[j] += (gi[j] * inv[gii]) % p;
		}
	}
	
	//test( result, "result" );
	
	for ( int i = 0; i < p; i++ )
		cout << (result[i] % p) << " ";
	cout << endl;
	
	return 0;
}