topic
Click here to look at the subject.
analysis
The first step may be \ (A \) array is converted into a probability \ (P (J) \) : each step or iso \ (J \) probability.
Subsequently found, \ (X \) from \ (0 \) becomes \ (I \) is equal to a desired \ (X \) from \ (I \) becomes \ (0 \) desired.
So our starting point, although not the same, but the end point is the same. In this way we can apply the model of random walk:
\ (f (i) \) : From \ (i \) becomes the starting point \ (0 \) expectations.
Boundary conditions \ (f (0) = 0 \) , the rest of the transfer as follows:
We found that \ (f \) is a similar "rolling their own own" transfer. But yet not the same, because more constant -1.
We put it into the form of convolution:
We found a rolled-up can not be determined how much of the 0, because our border transfer is \ (f (0) = 0 \) .
But we roll out the first set to 0 \ (the X-\) , you can get:
In other words, we should roll out of something original \ (f \) and is the same.
May then be obtained \ (X = F (0) + ^ n-2. 1-\) :
We found that \ (f \) vector and vector comparison results like, and there are public part, we can consider soda:
After this we can use to obtain transform FWT \ (f \) vector.
But we will be the first case of 0 is 0 after the discovery of FWT, not at this time inversion yuan.
However, while \ (f (0) \) values after conversion \ (f '(0) \ ) is unrestricted. Therefore, we can give \ (f '(0) \ ) into an arbitrary value, such as \ (0 \) . 0 after the first inverse transformation is \ (k \) . \ (f \) in each of you will contribute more \ (k \) , like to lose.
Code
#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;
}