$\newcommand{\O}{\mathrm{O}}$
高速 Walsh-Hadamrd 変換. 高速フーリエ変換の亜種で FFT が $c[k] = \underset{i+j=k}{\mathrm{sum}} a[i] \times b[j]$ を満たす $c$ を求めるのに対し,
$c[k] = \underset{i \oplus j=k}{\mathrm{sum}} a[i] \times b[j]$ を満たす $c$ を求めるアルゴリズム(xor-convolution).
xor 以外にも係数行列を少し変えれば and, or についても求めることが可能である.
時間計算量: $\O (n \log n)$
#define MOD 1000000007 inline int add(int x, int y) { return (x + y)%MOD; } inline int sub(int x, int y) { return (x+MOD-y)%MOD; } inline int mul(int x, int y) { return (long long)x*y%MOD; } inline int mod_pow(int a, int b) { int res = 1; while(b){ if(b & 1){ res = mul(res, a); } a = mul(a, a); b >>= 1; } return res; } // xor convolution void fwht(vector<int>& poly, bool rev=false){ int n = (int)poly.size(); for(int i = 1; i < n; i *= 2){ for(int j = 0; j < i; j++){ for(int k = 0; k < n; k += i*2){ int u = poly[j+k], v = poly[j+k+i]; poly[j+k] = add(u, v); poly[j+k+i] = sub(u, v); } } } if(rev){ int inv = mod_pow(n, MOD-2); for(int i = 0; i < n; i++){ poly[i] = mul(poly[i], inv); } } } // or convolution // void fwht(vector<int>& poly, bool rev=false){ // int n = (int)poly.size(); // for(int i = 1; i < n; i *= 2){ // for(int j = 0; j < i; j++){ // for(int k = 0; k < n; k += i*2){ // if(rev){ // poly[j+k+i] = sub(poly[j+k+i], poly[j+k]); // }else{ // poly[j+k+i] = add(poly[j+k+i], poly[j+k]); // } // } // } // } // } // and convolution // void fwht(vector<int>& poly, bool rev=false){ // int n = (int)poly.size(); // for(int i = 1; i < n; i *= 2){ // for(int j = 0; j < i; j++){ // for(int k = 0; k < n; k += i*2){ // int u = poly[j+k], v = poly[j+k+i]; // if(rev){ // poly[j+k] = sub(v, u); // poly[j+k+i] = u; // }else{ // poly[j+k] = v; // poly[j+k+i] = add(u, v); // } // } // } // } // } vector<int> mul(vector<int> a, vector<int> b){ int sm = (int)a.size() + (int)b.size() - 1, size_ = 1; while(size_ < sm) size_ *= 2; a.resize(size_, 0), b.resize(size_, 0); fwht(a), fwht(b); for(int i = 0; i < size_; i++){ a[i] = mul(a[i], b[i]); } fwht(a, true); a.resize(sm); return a; }
yosupo さんの library checker : Bitwise Xor Convolution
提出コード (xor convolution の verify)
yosupo さんの library checker : Bitwise And Convolution
提出コード (and convolution の verify)