voidForT(modint *f){ for (int k = 1; k < n; k *=2){ for (int i = 0; i < n; i += 2*k){ for (int j = 0; j < k; j++){ // f[i+j] = f[i+j]; f[i+j+k] += f[i+j]; } } } }
voidIForT(modint *f){ for (int k = 1; k < n; k *=2){ for (int i = 0; i < n; i += 2*k){ for (int j = 0; j < k; j++){ f[i+j+k] -= f[i+j]; } } } }
合并
1 2 3 4 5 6 7 8 9 10 11
// Or卷积 voidForT(vector<modint> &f,int flag = 1/* 1:正变换,-1:逆变换 */){ int n = f.size(); for (int k = 1; k < n; k *=2){ for (int i = 0; i < n; i += 2*k){ for (int j = 0; j < k; j++){ f[i+j+k] += flag * f[i+j]; } } } }
voidFandT(vector<modint> &f, int flag = 1/* 1:正变换,-1:逆变换 */){ int n = f.size(); for (int k = 1; k < n; k *=2){ for (int i = 0; i < n; i += 2*k){ for (int j = 0; j < k; j++){ f[i+j] += f[i+j+k] * flag; } } } }
voidFWHT(vector<modint> &f, int flag = 1/* 1: 正变换, 1/2: 逆变换*/){ int n = f.size(); for (int k = 1; k < n; k *=2){ for (int i = 0; i < n; i += 2*k){ for (int j = 0; j < k; j++){ auto U = f[i+j]; auto T = f[i+j+k]; f[i+j] = U + T; f[i+j+k] = U - T; f[i+j] *= flag; f[i+j+k] *= flag; } } } }
typedeflonglong ll; #define rep(i,a,n) for (ll i=a;i<n;i++) #define per(i,a,n) for (ll i=n;i-->(ll)a;) #define pb push_back
using MODINT::modint;
namespace FWT{ voidForT(vector<modint> &f,int flag = 1/* 1:正变换,-1:逆变换 */){ int n = f.size(); for (int k = 1; k < n; k *=2){ for (int i = 0; i < n; i += 2*k){ for (int j = 0; j < k; j++){ f[i+j+k] += f[i+j] * flag; } } } }
voidFandT(vector<modint> &f, int flag = 1/* 1:正变换,-1:逆变换 */){ int n = f.size(); for (int k = 1; k < n; k *=2){ for (int i = 0; i < n; i += 2*k){ for (int j = 0; j < k; j++){ f[i+j] += f[i+j+k] * flag; } } } } voidIFandT(vector<modint> &f){FandT(f, -1);}
modint inv2 = modint(2).inv(); voidFWHT(vector<modint> &f, modint flag = 1/* 1: 正变换, 1/2: 逆变换*/){ int n = f.size(); for (int k = 1; k < n; k *=2){ for (int i = 0; i < n; i += 2*k){ for (int j = 0; j < k; j++){ auto U = f[i+j]; auto T = f[i+j+k]; f[i+j] = U + T; f[i+j+k] = U - T; f[i+j] *= flag; f[i+j+k] *= flag; } } } } voidIFWHT(vector<modint> &f){FWHT(f, inv2);} voidFxorT(vector<modint> &f,int flag = 1){FWHT(f, flag);} voidIFxorT(vector<modint> &f){IFWHT(f);}
// --- or --- { auto A = A0; auto B = B0; auto C = FWT::or_convolution(A,B); print(C); } // --- and --- { auto A = A0; auto B = B0; auto C = FWT::and_convolution(A,B); print(C); } // --- xor --- { auto A = A0; auto B = B0; auto C = FWT::xor_convolution(A,B); print(C); } return0; }
// ----------- fwt ----------- using MODINT::modint;
namespace FWT{ voidForT(vector<modint> &f,int flag = 1/* 1:正变换,-1:逆变换 */){ int n = f.size(); for (int k = 1; k < n; k *=2){ for (int i = 0; i < n; i += 2*k){ for (int j = 0; j < k; j++){ f[i+j+k] += f[i+j] * flag; } } } }
voidFandT(vector<modint> &f, int flag = 1/* 1:正变换,-1:逆变换 */){ int n = f.size(); for (int k = 1; k < n; k *=2){ for (int i = 0; i < n; i += 2*k){ for (int j = 0; j < k; j++){ f[i+j] += f[i+j+k] * flag; } } } } voidIFandT(vector<modint> &f){FandT(f, -1);}
modint inv2 = modint(2).inv(); voidFWHT(vector<modint> &f, modint flag = 1/* 1: 正变换, 1/2: 逆变换*/){ int n = f.size(); for (int k = 1; k < n; k *=2){ for (int i = 0; i < n; i += 2*k){ for (int j = 0; j < k; j++){ auto U = f[i+j]; auto T = f[i+j+k]; f[i+j] = U + T; f[i+j+k] = U - T; f[i+j] *= flag; f[i+j+k] *= flag; } } } } voidIFWHT(vector<modint> &f){FWHT(f, inv2);} voidFxorT(vector<modint> &f,int flag = 1){FWHT(f, flag);} voidIFxorT(vector<modint> &f){IFWHT(f);}
intmain(){ constint n = read(); constint SIZE = 1<<n; // 长度2的幂次 auto A0 = vector<modint>(SIZE,0); auto B0 = vector<modint>(SIZE,0); rep(i,0,SIZE) A0[i] = read(); rep(i,0,SIZE) B0[i] = read();
// --- or --- { auto A = A0; auto B = B0; auto C = FWT::or_convolution(A,B); print(C); } // --- and --- { auto A = A0; auto B = B0; auto C = FWT::and_convolution(A,B); print(C); } // --- xor --- { auto A = A0; auto B = B0; auto C = FWT::xor_convolution(A,B); print(C); } return0; }