题目描述
给定长度为 2 n 2^n 2n两个序列 A , B A,B A,B,设 C i = ∑ j ⊕ k = i A j B k C_i=\sum_{j\oplus k=i}A_jB_k Ci=∑j⊕k=iAjBk 分别当 ⊕ \oplus ⊕是or,and,xor时求出C
输入格式
第一行一个数n。 第二行 2 n 个 数 A 0 . . A 2 n − 1 2^n个数A_0..A_{2^n-1} 2n个数A0..A2n−1第三行 2 n 个 数 B 0 . . B 2 n − 1 2^n个数B_0..B_{2^n-1} 2n个数B0..B2n−1
输出格式
三行每行 2 n 2^n 2n个数,分别代表 ⊕ \oplus ⊕是or,and,xor时 C 0 . . C 2 n − 1 C_0..C_{2^n-1} C0..C2n−1的值   m o d   998244353 \bmod\ 998244353 mod 998244353
输入输出样例
输入 #1
2
2 4 6 8
1 3 5 7
输出 #1
2 22 46 250
88 64 112 56
100 92 68 60
说明/提示
n≤17n。
#include<cstdio>
#include<iostream>
#include<tuple>
#include<algorithm>
using namespace std;
const int mod = 998244353,inv2 = (mod + 1) >> 1;
typedef long long ll;
inline static const void reduce(int&x){x+=x>>31&mod;}
inline static const void mulor(int*a,int*b,int*c,int lm){
if(!(lm/=2))return void(*c=ll(*a)**b%mod);
for(int i=0;i<lm;++i)reduce(a[i+lm]+=a[i]-mod),reduce(b[i+lm]+=b[i]-mod);
mulor(a,b,c,lm),mulor(a+lm,b+lm,c+lm,lm);
for(int i=0;i<lm;++i)reduce(c[i+lm]-=c[i]);
}
inline static const void muland(int*a,int*b,int*c,int lm){
if(!(lm/=2))return void(*c=ll(*a)**b%mod);
for(int i=0;i<lm;++i)reduce(a[i]+=a[i+lm]-mod),reduce(b[i]+=b[i+lm]-mod);
muland(a,b,c,lm),muland(a+lm,b+lm,c+lm,lm);
for(int i=0;i<lm;++i)reduce(c[i]-=c[i+lm]);
}
inline static const void mulxor(int*a,int*b,int*c,int lm){
if(!(lm/=2))return void(*c=ll(*a)**b%mod);
for(int i=0;i<lm;++i){
tie(a[i],a[i+lm])=make_tuple(a[i]+a[i+lm],a[i]-a[i+lm]);
tie(b[i],b[i+lm])=make_tuple(b[i]+b[i+lm],b[i]-b[i+lm]);
reduce(a[i+lm]),reduce(b[i+lm]),reduce(a[i]-=mod),reduce(b[i]-=mod);
}
mulxor(a,b,c,lm),mulxor(a+lm,b+lm,c+lm,lm);
for(int i=0;i<lm;++i)tie(c[i],c[i+lm])=make_tuple(ll(c[i]+c[i+lm])*inv2%mod,ll(c[i]-c[i+lm]+mod)*inv2%mod);
}
int n;
int a[1 << 17],b[1 << 17],c[1 << 17];
int d[1 << 17],e[1 << 17],f[1 << 17];
int g[1 << 17],h[1 << 17],i[1 << 17];
int main(){
ios::sync_with_stdio(false),cin.tie(0);
cin >> n;
for(int i=0;i<1<<n;++i)cin >> a[i],d[i]=g[i]=a[i];
for(int i=0;i<1<<n;++i)cin >> b[i],e[i]=h[i]=b[i];
mulor(a,b,c,1<<n);
muland(d,e,f,1<<n);
mulxor(g,h,i,1<<n);
for(int i=0;i<1<<n;++i)cout << c[i] << ' ';
cout << '\n';
for(int i=0;i<1<<n;++i)cout << f[i] << ' ';
cout << '\n';
for(int i=0;i<1<<n;++i)cout << ::i[i] << ' ';
}