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# (Mono 4.6.2.0) (judge verdict: Time Limit Exceeded)

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using F = mlong;

class TEST{
	static void Main(){
		Sol mySol =new Sol();
		mySol.Solve();
	}
}

class Sol{
	public void Solve(){
		
		mlong.mod = P;
		int N = P;
		var LI = new LagrangeInterporation();
		mlong[] X = new mlong[N];
		mlong[] Y = new mlong[N];
		for(int i=0;i<N;i++){
			X[i] = i;
			Y[i] = A[i];
		}
		LI.Init(N, X, Y);
		var ans = LI.Calc();
		
		Console.WriteLine(String.Join(" ",ans));
		
	}
	int P;
	int[] A;
	public Sol(){
		P = ri();
		A = ria();
	}

	static String rs(){return Console.ReadLine();}
	static int ri(){return int.Parse(Console.ReadLine());}
	static long rl(){return long.Parse(Console.ReadLine());}
	static double rd(){return double.Parse(Console.ReadLine());}
	static String[] rsa(char sep=' '){return Console.ReadLine().Split(sep);}
	static int[] ria(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>int.Parse(e));}
	static long[] rla(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>long.Parse(e));}
	static double[] rda(char sep=' '){return Array.ConvertAll(Console.ReadLine().Split(sep),e=>double.Parse(e));}
}



class LagrangeInterporation{
	// given: N - pairs (X, Y)
	// return: F-coefficient Polinomial of deg <= N - 1;
	// complexity: O(N ^ 2)
	// requirement: F : field ??
	F[] X;
	F[] Y;
	int N;
	
	public void Init(int n, F[] x, F[] y){
		N = n;
		X = new F[N];
		Y = new F[N];
		for(int i=0;i<N;i++){
			X[i] = x[i];
			Y[i] = y[i];
		}
		// X check:
		var h = new HashSet<F>();
		for(int i=0;i<N;i++) h.Add(X[i]);
		if(h.Count < N){
			throw new Exception("X must be different each other");
		}
	}
	
	public F[] Calc(){
		
		// p0[x]: (x - X[0])(x - X[1])(x - X[2])...(x - X[N-1])
		// polynomial, deg = N, 
		F[] p0 = new F[N + 1];
		p0[0] = (F) 1;
		
		// expansion:
		//   p0 = p0[0] + p0[1] * x^1 + p0[2] * x^2 + ... + p0[N] * x^N
		for(int j=0;j<N;j++){
			var np0 = new F[N + 1];
			for(int i=0;i<=N;i++){
				if(p0[i] == 0) continue;
				np0[i + 1] += p0[i];
				np0[i] += -1 * X[j] * p0[i];
			}
			p0 = np0;
		}
		
		// 
		//   Sum { Y[i] * fi[x] / fi[x = X[i]] } for i in [0,N)
		//     where fi[x] = p0[x] / (x - X[i])
		F[][] p = new mlong[N][];
		for(int i=0;i<N;i++){
			
			F[] fi = new F[N];
			
			// calc fi[x] = p0[x] / (x - X[i]) as polynomial
			F res = (F) 0;
			for(int j=N-1;j>=0;j--){
				F x1 = p0[j + 1] - res;
				F x0 = p0[j];
				fi[j] = x1;
				res = fi[j] * (-1 * X[i]);
			}
			
			// v = fi[x_i = i]:
			F v = (F) 0;
			F x = (F) 1;
			for(int j=0;j<N;j++){
				v += x * fi[j];
				x *= X[i];
			}
			
			// fi / fi[x = X[i]] * Y[i]
			if(v == (F) 0) throw new Exception("Zero Divide");
			F coef = (F) 1 / v * Y[i];
			for(int j=0;j<N;j++) fi[j] *= coef;
			
			p[i] = new F[N];
			for(int j=0;j<N;j++) p[i][j] = fi[j];
			
		}
		
		// Sum up
		F[] ret = new F[N];
		for(int i=0;i<N;i++){
			for(int j=0;j<N;j++){
				ret[i] += p[j][i];
			}
		}
		
		return ret;
	}
	
}

struct mlong {
	
	public static long mod = (long) 1e9 + 7;
	long V;
	
	public mlong(long _v = 0){
		V = _v;
	}
	
	public static mlong operator+(mlong a, mlong b){
		var v0 = a.V + b.V; if(v0 >= mod) v0 -= mod;
		return new mlong(v0);
	}
	public static mlong operator-(mlong a, mlong b){
		var v0 = mod + a.V - b.V; if(v0 >= mod) v0 -= mod;
		return new mlong(v0);
	}
	public static mlong operator*(mlong a, mlong b){
		var v0 = a.V * b.V; if(v0 >= mod) v0 %= mod;
		return new mlong(v0);
	}
	public static mlong operator/(mlong a, mlong b){
		var v0 = a.V * inv(b.V).V; if(v0 >= mod) v0 %= mod;
		return new mlong(v0);
	}
	
	
	public static mlong inv(long x){
		long a = 0, b = 0, c = 0;
		ExtGCD(x, mod, ref a, ref b, ref c);
		return (mlong)((a + mod) % mod);
	}
	
	public static void ExtGCD(long x, long y, ref long a, ref long b, ref long c){
		long r0 = x; long r1 = y;
		long a0 = 1; long a1 = 0;
		long b0 = 0; long b1 = 1;
		long q1, r2, a2, b2;
		while(r1 > 0){
			q1 = r0 / r1;
			r2 = r0 % r1;
			a2 = a0 - q1 * a1;
			b2 = b0 - q1 * b1;
			r0 = r1; r1 = r2;
			a0 = a1; a1 = a2;
			b0 = b1; b1 = b2;
		}
		c = r0;
		a = a0;
		b = b0;
	}
	
	public static mlong ModPow(mlong a, long k){
		if(k == 0) return (mlong) 1;
		if(a == 0) return (mlong) 0;
		mlong x = a;
		mlong ret = 1;
		while(k > 0){
			if(k % 2 == 1) ret *= x;
			x *= x;
			k >>= 1;
		}
		return ret;
	}
	
	
	public static bool operator == (mlong a, mlong b){
		 return a.Equals(b);
	}
	public static bool operator != (mlong a, mlong b){
		 return !(a == b);
	}
	
	public override bool Equals(System.Object obj){
		if(obj  ==  null) return false;
		mlong p  =  (mlong) obj;
		if((System.Object) p  ==  null) return false;
		return p.V  ==  V;
	}
	public override int GetHashCode(){
		return V.GetHashCode();
	}
	
	public static implicit operator mlong(long n){
		long v = n % mod; if(v < 0) v += mod;
		return new mlong(v);
	}
	public static implicit operator mlong(int n){
		long v = n % mod; if(v < 0) v += mod;
		return new mlong(v);
	}
	public static explicit operator long(mlong n){
		return n.V;
	}
	
	public override String ToString(){
		return V.ToString();
	}
	
	
}