set/and-convolution.hpp
Depends on
Verified with
Code
#pragma once
#include "./zeta-mobius-transform.hpp"
template < class T >
vector < T > AndConvolution ( vector < T > a , vector < T > b ) {
assert ( a . size () == b . size ());
SupsetZetaTransform ( a );
SupsetZetaTransform ( b );
for ( int i = 0 ; i < a . size (); i ++ ) a [ i ] *= b [ i ];
SupsetMobiusTransform ( a );
return a ;
}
#line 2 "set/and-convolution.hpp"
#line 2 "set/zeta-mobius-transform.hpp"
template < class T >
void SupsetZetaTransform ( vector < T >& f ) {
int n = f . size ();
assert (( n & ( n - 1 )) == 0 );
for ( int i = 1 ; i < n ; i <<= 1 )
for ( int j = 0 ; j < n ; j += i * 2 )
for ( int k = 0 ; k < i ; k ++ )
f [ j + k ] += f [ i + j + k ];
}
template < class T >
void SupsetMobiusTransform ( vector < T >& f ) {
int n = f . size ();
assert (( n & ( n - 1 )) == 0 );
for ( int i = 1 ; i < n ; i <<= 1 )
for ( int j = 0 ; j < n ; j += i * 2 )
for ( int k = 0 ; k < i ; k ++ )
f [ j + k ] -= f [ i + j + k ];
}
template < class T >
void SubsetZetaTransform ( vector < T >& f ) {
int n = f . size ();
assert (( n & ( n - 1 )) == 0 );
for ( int i = 1 ; i < n ; i <<= 1 )
for ( int j = 0 ; j < n ; j += i * 2 )
for ( int k = 0 ; k < i ; k ++ )
f [ i + j + k ] += f [ j + k ];
}
template < class T >
void SubsetMobiusTransform ( vector < T >& f ) {
int n = f . size ();
assert (( n & ( n - 1 )) == 0 );
for ( int i = 1 ; i < n ; i <<= 1 )
for ( int j = 0 ; j < n ; j += i * 2 )
for ( int k = 0 ; k < i ; k ++ )
f [ i + j + k ] -= f [ j + k ];
}
#line 4 "set/and-convolution.hpp"
template < class T >
vector < T > AndConvolution ( vector < T > a , vector < T > b ) {
assert ( a . size () == b . size ());
SupsetZetaTransform ( a );
SupsetZetaTransform ( b );
for ( int i = 0 ; i < a . size (); i ++ ) a [ i ] *= b [ i ];
SupsetMobiusTransform ( a );
return a ;
}
Back to top page