Time Complexity: O ( N log N ) \mathcal O(N \log N) O ( N log N )
We're asked to evaluate a polynomial at N N N points, which implies that our
solution will involve the Fast Fourier Transform. Indeed, our solution is mostly
based on the idea behind the Discrete Fourier Transform - that
P ( x ) = P e v e n ( x 2 ) + x ⋅ P o d d ( x 2 ) P(x) = P_{even}(x^2) + x \cdot P_{odd}(x^2) P ( x ) = P e v e n ( x 2 ) + x ⋅ P o dd ( x 2 ) for any polynomial P P P .
Let solve ( k , P ) = ( P ( q k i ) m o d M ) i = 0 N / k \texttt{solve}(k, P) = (P(q^{ki}) \bmod M)_{i = 0}^{N / k} solve ( k , P ) = ( P ( q ki ) mod M ) i = 0 N / k . Our answer
will be solve ( 1 , W ) \texttt{solve}(1, W) solve ( 1 , W ) , and we will compute solve ( k , P ) \texttt{solve}(k, P) solve ( k , P )
recursively in O ( N k log N k ) \mathcal O(\frac{N}{k} \log \frac{N}{k}) O ( k N log k N ) time.
First, precompute all q i m o d M q^i \bmod M q i mod M . If k = N k = N k = N , then P P P is a constant
polynomial. and can be evaluated in constant time. Otherwise, let
v = solve ( k , P ) v = \texttt{solve}(k, P) v = solve ( k , P ) , u even = solve ( 2 k , P even ) u_\text{even} = \texttt{solve}(2k, P_\text{even}) u even = solve ( 2 k , P even ) ,
and u odd = solve ( 2 k , P odd ) u_\text{odd} = \texttt{solve}(2k, P_\text{odd}) u odd = solve ( 2 k , P odd ) . We have two cases when
computing each v [ i ] v[i] v [ i ] :
Case 1:
i < N 2 k i < \frac{N}{2k} i < 2 k N :
v [ i ] = P ( q k i ) m o d M = ( P even ( q 2 k i ) + q k i ⋅ P odd ( q 2 k i ) ) m o d M = ( u even [ i ] + q k i ⋅ u odd [ i ] ) m o d M \begin{aligned} v[i] &= P(q^{ki}) \bmod M\\ &= (P_\text{even}(q^{2ki}) + q^{ki} \cdot P_\text{odd}(q^{2ki})) \bmod M\\ &= (u_\text{even}[i] + q^{ki} \cdot u_\text{odd}[i]) \bmod M \end{aligned} v [ i ] = P ( q ki ) mod M = ( P even ( q 2 ki ) + q ki ⋅ P odd ( q 2 ki )) mod M = ( u even [ i ] + q ki ⋅ u odd [ i ]) mod M
Case 2:
i ≥ N 2 k i \geq \frac{N}{2k} i ≥ 2 k N . In this case, let
i = N 2 k + j i = \frac{N}{2k} + j i = 2 k N + j :
v [ i ] = P ( q N 2 + k j ) m o d M = ( P even ( q N ⋅ q 2 k j ) + q k i ⋅ P odd ( q N ⋅ q 2 k j ) ) m o d M = ( P even ( q 2 k j ) + q k i ⋅ P odd ( q 2 k j ) ) m o d M = ( u even [ j ] + q k i ⋅ u odd [ j ] ) m o d M \begin{aligned} v[i] &= P(q^{\frac{N}{2} + kj}) \bmod M\\ &= (P_\text{even}(q^N \cdot q^{2kj}) + q^{ki} \cdot P_\text{odd}(q^N \cdot q^{2kj})) \bmod M\\ &= (P_\text{even}(q^{2kj}) + q^{ki} \cdot P_\text{odd}(q^{2kj})) \bmod M\\ &= (u_\text{even}[j] + q^{ki} \cdot u_\text{odd}[j]) \bmod M \end{aligned} v [ i ] = P ( q 2 N + kj ) mod M = ( P even ( q N ⋅ q 2 kj ) + q ki ⋅ P odd ( q N ⋅ q 2 kj )) mod M = ( P even ( q 2 kj ) + q ki ⋅ P odd ( q 2 kj )) mod M = ( u even [ j ] + q ki ⋅ u odd [ j ]) mod M
Putting this all together, we get:
v [ i ] = ( u even [ i m o d N 2 k ] + p k i ⋅ u odd [ i m o d N 2 k ] ) m o d M v[i] = \left(u_\text{even}\left[i \bmod \frac{N}{2k}\right] + p^{ki} \cdot u_\text{odd}\left[i \bmod \frac{N}{2k}\right]\right) \bmod M v [ i ] = ( u even [ i mod 2 k N ] + p ki ⋅ u odd [ i mod 2 k N ] ) mod M
Copy # include <bits/stdc++.h>
typedef long long ll ;
using namespace std ;
int n ;
ll m , q , a [ 1 << 20 ] , q_pow [ 1 << 20 ] ;
vector < ll > dft ( int k = 1 , int idx = 0 ) {
if ( k == n ) return { a [ idx ] } ;
else {