título
Haga clic aquí para ver el tema.
análisis
La primera etapa puede ser \ (A \) matriz se convierte en una probabilidad \ (P (J) \) : cada paso o iso \ (J \) de probabilidad.
Posteriormente encontrado, \ (X \) de \ (0 \) se convierte en \ (I \) es igual a una deseada \ (X \) de \ (I \) se convierte en \ (0 \) deseado.
Así que nuestro punto de partida, aunque no es la misma, pero el punto final es el mismo. De esta manera podemos aplicar el modelo de paseo aleatorio:
\ (f (i) \) : De \ (i \) se convierte en el punto de partida \ \ (0) expectativas.
Las condiciones de contorno \ (f (0) = 0 \) , el resto de la transferencia de la siguiente forma:
Encontramos que \ (f \) es un semejante "rodar su propio propia" transferencia. Pero todavía no es el mismo, porque más constante -1.
Nos ponemos en forma de convolución:
Encontramos un enrollado no se puede determinar cuánto del 0, porque nuestra frontera es la transferencia de \ (f (0) = 0 \) .
Pero que rollo a cabo el primer set a 0 \ (los ejes X \) , se puede obtener:
En otras palabras, debemos despliegue de algo original \ (f \) y es el mismo.
Puede entonces ser obtenido \ (X = F (0) + ^ n-2 1- \.) :
Encontramos que \ (f \) Resultados del vector y el vector de comparación gusta, y hay parte pública, podemos considerar la soda:
Después de esto podemos utilizar para obtener la transformada FWT \ (f \) del vector.
Pero vamos a ser el primer caso de 0 es 0 después del descubrimiento del FWT, no en este momento yuanes de inversión.
Sin embargo, mientras que \ (f (0) \) valores después de la conversión \ (f '(0) \ ) es sin restricciones. Por lo tanto, podemos dar \ (f '(0) \ ) en un valor arbitrario, como \ (0 \) . 0 después de la primera transformación inversa es \ (k \) . \ (F \) en cada uno de ustedes va a contribuir más \ (k \) , al igual que perder.
código
#include <cstdio>
const int mod = 998244353, inv2 = 499122177;
const int MAXN = 20, MAXL = ( 1 << 18 ) + 5;
template<typename _T>
void read( _T &x )
{
x = 0;char s = getchar();int f = 1;
while( s > '9' || s < '0' ){if( s == '-' ) f = -1; s = getchar();}
while( s >= '0' && s <= '9' ){x = ( x << 3 ) + ( x << 1 ) + ( s - '0' ), s = getchar();}
x *= f;
}
template<typename _T>
void write( _T x )
{
if( x < 0 ){ putchar( '-' ); x = ( ~ x ) + 1; }
if( 9 < x ){ write( x / 10 ); }
putchar( x % 10 + '0' );
}
int F[MAXL], p[MAXL], h[MAXL];
int N, len;
int qkpow( int base, int indx )
{
int ret = 1;
while( indx )
{
if( indx & 1 ) ret = 1ll * ret * base % mod;
base = 1ll * base * base % mod, indx >>= 1;
}
return ret;
}
int inv( const int a ) { return qkpow( a, mod - 2 ); }
int fix( const int x ) { return ( x % mod + mod ) % mod; }
void FWT( int *f, const int mode )
{
int t1, t2;
for( int s = 2 ; s <= len ; s <<= 1 )
for( int i = 0, t = s >> 1 ; i < len ; i += s )
for( int j = i ; j < i + t ; j ++ )
{
t1 = f[j], t2 = f[j + t];
if( mode > 0 ) f[j] = ( t1 + t2 ) % mod, f[j + t] = fix( t1 - t2 );
else f[j] = 1ll * ( t1 + t2 ) * inv2 % mod, f[j + t] = 1ll * fix( t1 - t2 ) * inv2 % mod;
}
}
int main()
{
int s = 0;
read( N ); len = 1 << N;
for( int i = 0 ; i < len ; i ++ ) read( p[i] ), s = ( s + p[i] ) % mod;
s = inv( s );
for( int i = 0 ; i < len ; i ++ ) p[i] = 1ll * p[i] * s % mod;
for( int i = 1 ; i < len ; i ++ ) h[i] = mod - 1;
h[0] = len - 1, p[0] = fix( p[0] - 1 );
FWT( h, 1 ), FWT( p, 1 );
for( int i = 1 ; i < len ; i ++ ) F[i] = 1ll * h[i] * inv( p[i] ) % mod;
FWT( F, -1 );
int tmp = mod - F[0];
for( int i = 0 ; i < len ; i ++ ) write( ( tmp + F[i] ) % mod ), putchar( '\n' );
return 0;
}