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 Java8 (OpenJDK 1.8.0) (judge verdict: Wrong Answer)

import java.util.Scanner;

public class Main {
	
	public static void main(String[] args) {
		Main obj = new Main();
		obj.exec();
	}
	
	public void exec() {
		Scanner sc = new Scanner(System.in);
		int p = Integer.parseInt(sc.nextLine());
		String[] strArr = sc.nextLine().split(" ");
		sc.close();
		int[] aArr = new int[p];
		for(int i = 0; i < p ; i++) {
			aArr[i] = Integer.parseInt(strArr[i]);
		}
		
		int[] factArr = new int[p];
		int[] recipFactArr = new int[p]; 
		
		factArr[0] = 1;
		recipFactArr[0] = 1; 
		makeFactArr(factArr, recipFactArr, p);
		int[] coefArr = new int[p];
		for(int i = 0; i < p; i++) {
			if(aArr[i] == 0) {
				continue;
			}
			coefArr[p - 1] = (coefArr[p - 1] + munusSurplus(-1, p)) % p;
			int powValue = 1;
			for(int j = 1; j <= p - 1; j++) {
				powValue = (powValue * i) % p;
				int addValue;
				int factValue = factArr[p - 1] * recipFactArr[j] * recipFactArr[p - 1 - j];
				if(j % 2 == 0) {
					addValue = munusSurplus(factValue * powValue * (-1), p);
				}else {
					addValue = (factValue * powValue) % p;
				}
				coefArr[p - 1 - j] = (coefArr[p - 1 - j] + addValue)%p;
			}
			coefArr[0] = (coefArr[0] + 1) % p;
//			System.out.println(Arrays.toString(coefArr));
		}
		
		for(int i = 0; i < p; i++) {
			System.out.print(coefArr[i]);
			if(i == p - 1) {
				System.out.print("\n");
			}else {
				System.out.print(" ");
			}
		}
		System.out.flush();
	}
	
	public long fact(long n) {
		long result = 1;
		for(long i = 1;i <= n;i++ ) {
			result *= i;
		}
		return result;
	}
	
	public void makeFactArr(int[] factArr, int[] recipFactArr, int base) {
		for(int i = 1; i < factArr.length; i++) {
			factArr[i] = (factArr[i-1] * i) % base;
			recipFactArr[i] = (recipFactArr[i-1]*makePowWithBase(i, base - 2, base))  % base;
 		}
	}
	
	public int makePowWithBase(int value, int time, int base) {
		int retVal = 1;
		for(int i = 0; i < time; i++) {
			retVal = (retVal * value)%base;
		}
		return retVal;
	}
	
	public int munusSurplus(int value, int base) {
		
		assert(value < 0);
		int invValue = value * (-1);
		if(invValue % base == 0) {
			return 0;
		}
		int x = invValue / base;
		return value + ((x + 1) * base);
	}

}