-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathFWT.cpp
31 lines (31 loc) · 930 Bytes
/
FWT.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/* xor convolution:
* x = (x0,x1) , y = (y0,y1)
* z = ( x0y0 + x1y1 , x0y1 + x1y0 )
* =>
* x' = ( x0+x1 , x0-x1 ) , y' = ( y0+y1 , y0-y1 )
* z' = ( ( x0+x1 )( y0+y1 ) , ( x0-x1 )( y0-y1 ) )
* z = (1/2) * z''
* or convolution:
* x = (x0, x0+x1), inv = (x0, x1-x0) w/o final div
* and convolution:
* x = (x0+x1, x1), inv = (x0-x1, x1) w/o final div */
const int MAXN = (1<<20)+10;
inline LL inv( LL x ) {
return mypow( x , MOD-2 );
}
inline void fwt( LL x[ MAXN ] , int N , bool inv=0 ) {
for( int d = 1 ; d < N ; d <<= 1 ) {
int d2 = d<<1;
for( int s = 0 ; s < N ; s += d2 )
for( int i = s , j = s+d ; i < s+d ; i++, j++ ){
LL ta = x[ i ] , tb = x[ j ];
x[ i ] = ta+tb;
x[ j ] = ta-tb;
if( x[ i ] >= MOD ) x[ i ] -= MOD;
if( x[ j ] < 0 ) x[ j ] += MOD;
} }
if( inv )
for( int i = 0 ; i < N ; i++ ) {
x[ i ] *= inv( N );
x[ i ] %= MOD;
} }