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 (GCC 5.4.1) (judge verdict: Accepted)

#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <limits.h>
int acs(const void *a, const void *b){return *(int*)a - *(int*)b;} /* 1,2,3,4.. */
int des(const void *a, const void *b){return *(int*)b - *(int*)a;} /* 8,7,6,5.. */
#define min(a,b) (a < b ? a: b)
#define max(a,b) (a > b ? a: b)

#define MAXN (2999)
// #define MOD (1000000007)
int64_t MOD;

// べき乗余
int64_t modpow(int64_t b, int64_t e)
{
    int64_t result = 1;
    while(e>0)
    {
        if(e&1) result = (result * b) % MOD;
        e >>= 1;
        b = (b * b) % MOD;
    }
    return result;
}

// 組み合わせ数
// nCk % MOD
// c[i] : i = 0～n
void getComb(int64_t* c, int n)
{
    c[0] = 1;
    for(int i=1;i<=n;i++)
    {
        // モジュラ逆数 = a^-1 = a^m-2 (m=素数のとき)
        c[i] = (((c[i-1] * (n-i+1) ) % MOD) * modpow(i, MOD-2)) % MOD;
    }
}

int64_t a[MAXN];
int64_t b[MAXN];
int64_t ncj[MAXN];

int main(void)
{
    int64_t p;

    scanf("%ld",&p);
    MOD = p;

    for(int i=0;i<p;i++) scanf("%ld",&(a[i]));

    getComb(ncj, p-1);

    for(int64_t i=0;i<p;i++)
    {
        if(a[i]==0) continue;
        b[0] += 1;
        b[0] %= p;

        int64_t pw = 1;
        for(int64_t j=p-1;j>=0;j--)
        {
            b[j] -= (pw * ncj[j]) %p;
            b[j] = (b[j] + (p*p)) % p;
            pw = ((pw * -i) + (p*p)) % p;
        }
    }

    for(int i=0;i<p;i++) printf("%ld ", b[i]);

    return 0;
}