#pragma once
#include<cassert>
#include<vector>
#include"Mylib/Convolution/fast_mobius_transform_subset.cpp"
#include"Mylib/Convolution/fast_zeta_transform_subset.cpp"namespacehaar_lib{template<typenameT>std::vector<T>subset_convolution(std::vector<T>f,std::vector<T>g){constintN=f.size();assert((N&(N-1))==0&&"N must be a power of 2");assert(f.size()==g.size());constintK=__builtin_ctz(N);std::vector<std::vector<T>>F(K+1),G(K+1);for(inti=0;i<=K;++i){F[i].resize(N);G[i].resize(N);for(intj=0;j<N;++j){if(__builtin_popcount(j)==i){F[i][j]=f[j];G[i][j]=g[j];}}F[i]=fast_zeta_transform_subset(F[i]);G[i]=fast_zeta_transform_subset(G[i]);}std::vector<std::vector<T>>H(K+1,std::vector<T>(N));for(inti=0;i<=K;++i){for(intj=0;j<N;++j){for(ints=0;s<=i;++s){H[i][j]+=F[s][j]*G[i-s][j];}}}std::vector<T>ret(N);for(inti=0;i<=K;++i){autoh=fast_mobius_transform_subset(H[i]);for(intj=0;j<N;++j){if(__builtin_popcount(j)==i)ret[j]+=h[j];}}returnret;}}// namespace haar_lib
#line 2 "Mylib/Convolution/subset_convolution.cpp"
#include<cassert>
#include<vector>
#line 3 "Mylib/Convolution/fast_mobius_transform_subset.cpp"
#include<functional>
#line 5 "Mylib/Convolution/fast_mobius_transform_subset.cpp"
namespacehaar_lib{template<typenameT,typenameFunc=std::minus<T>>std::vector<T>fast_mobius_transform_subset(std::vector<T>f,constFunc&op=std::minus<T>()){constintN=f.size();assert((N&(N-1))==0&&"N must be a power of 2");for(inti=1;i<N;i<<=1){for(intj=0;j<N;++j){if(j&i)f[j]=op(f[j],f[j^i]);}}returnf;}}// namespace haar_lib#line 5 "Mylib/Convolution/fast_zeta_transform_subset.cpp"
namespacehaar_lib{template<typenameT,typenameFunc=std::plus<T>>std::vector<T>fast_zeta_transform_subset(std::vector<T>f,constFunc&op=std::plus<T>()){constintN=f.size();assert((N&(N-1))==0&&"N must be a power of 2");for(inti=1;i<N;i<<=1){for(intj=0;j<N;++j){if(j&i)f[j]=op(f[j],f[j^i]);}}returnf;}}// namespace haar_lib#line 6 "Mylib/Convolution/subset_convolution.cpp"
namespacehaar_lib{template<typenameT>std::vector<T>subset_convolution(std::vector<T>f,std::vector<T>g){constintN=f.size();assert((N&(N-1))==0&&"N must be a power of 2");assert(f.size()==g.size());constintK=__builtin_ctz(N);std::vector<std::vector<T>>F(K+1),G(K+1);for(inti=0;i<=K;++i){F[i].resize(N);G[i].resize(N);for(intj=0;j<N;++j){if(__builtin_popcount(j)==i){F[i][j]=f[j];G[i][j]=g[j];}}F[i]=fast_zeta_transform_subset(F[i]);G[i]=fast_zeta_transform_subset(G[i]);}std::vector<std::vector<T>>H(K+1,std::vector<T>(N));for(inti=0;i<=K;++i){for(intj=0;j<N;++j){for(ints=0;s<=i;++s){H[i][j]+=F[s][j]*G[i-s][j];}}}std::vector<T>ret(N);for(inti=0;i<=K;++i){autoh=fast_mobius_transform_subset(H[i]);for(intj=0;j<N;++j){if(__builtin_popcount(j)==i)ret[j]+=h[j];}}returnret;}}// namespace haar_lib