FWT_or
<p><img src="https://www.showdoc.com.cn/server/api/attachment/visitfile/sign/0f241db4f32930c57349b6a35d7d9c3a" alt="" />
<img src="https://www.showdoc.com.cn/server/api/attachment/visitfile/sign/596e90a00c59287366fa634157ebb8d1" alt="" /></p>
<pre><code class="language-cpp">#include <iostream>
using namespace std;
typedef long long ll;
const int maxn = 100005, mod = 998244353;
ll A[maxn], b[maxn];//注意从下标为0开始存值
void FWT_or(ll *a, int n, int opt = 1){
for(int i = 1; i < n; i <<= 1){
for(int p = i << 1, j = 0; j < n; j += p){
for(int k = 0; k < i; k++){
if(opt == 1) a[i+j+k] = (a[j+k] + a[i+j+k]) % mod;
else a[i+j+k] = (a[i+j+k] + mod - a[j+k]) % mod;
}
}
}
}
int main(){
int n, tn = 1; scanf("%d", &n);
//将最长的那个多项式的次数n进行变换得到tn
while(tn < 2 * n + 1) tn <<= 1;
FWT_or(A, tn), FWT_or(B, tn);
for(int i = 0; i < tn; i++) A[i] = A[i] * B[i] % mod;
FWT_or(A, tn, -1);
return 0;
}</code></pre>