Copyright: Oh ...... but still free to reprint please indicate the source of it: https://blog.csdn.net/dreaming__ldx/article/details/89041894
Portal
Template title
Water template
for
be used
, with the remaining two kinds of
like.
Of course, you can consider using divide and conquer multiplication.
Code:
#include<bits/stdc++.h>
#define ri register int
using namespace std;
const int rlen=1<<18|1;
inline char gc(){
static char buf[rlen],*ib,*ob;
(ib==ob)&&(ob=(ib=buf)+fread(buf,1,rlen,stdin));
return ib==ob?-1:*ib++;
}
inline int read(){
int ans=0;
char ch=gc();
while(!isdigit(ch))ch=gc();
while(isdigit(ch))ans=((ans<<2)+ans<<1)+(ch^48),ch=gc();
return ans;
}
typedef long long ll;
const int mod=998244353;
inline int add(const int&a,const int&b){return a+b>=mod?a+b-mod:a+b;}
inline int dec(const int&a,const int&b){return a>=b?a-b:a-b+mod;}
inline int mul(const int&a,const int&b){return (ll)a*b%mod;}
inline void update(int&a,const int&b){a=a+b>=mod?a+b-mod:a+b;}
int n,lim;
vector<int>a,b,c;
inline vector<int> solve(int up){
if(!up)return vector<int>(1,mul(a[0],b[0]));
int mid=up>>1;
vector<int> ret,tmp;
ret=solve(mid);
for(ri i=mid+1;i<=up;++i)update(a[i-mid-1],a[i]),update(b[i-mid-1],b[i]);
tmp=solve(mid);
puts("------");
for(ri i=0;i<=mid;++i)cerr<<ret[i]<<' ';
puts("");
for(ri i=0;i<=mid;++i)cerr<<tmp[i]<<' ';
puts("");
for(ri i=mid+1;i<=up;++i)a[i-mid-1]=dec(a[i-mid-1],a[i]),b[i-mid-1]=dec(b[i-mid-1],b[i]);
for(ri i=0;i<=mid;++i)ret.push_back(dec(tmp[i],ret[i]));
for(ri i=0;i<=up;++i)cerr<<ret[i]<<' ';
puts("");
puts("------");
return ret;
}
inline void fmt(vector<int>&a,const int&type){
for(ri mid=1;mid<lim;mid<<=1)for(ri i=0;i<lim;++i)
if(i&mid)a[i]=~type?add(a[i],a[i^mid]):dec(a[i],a[i^mid]);
}
inline void fwt_and(vector<int>&a,const int&type){
for(ri mid=1;mid<lim;mid<<=1)for(ri j=0,len=mid<<1;j<lim;j+=len)
for(ri k=0;k<mid;++k)a[j+k]=~type?add(a[j+k],a[j+k+mid]):dec(a[j+k],a[j+k+mid]);
}
inline void fwt_xor(vector<int>&a,const int&type){
int a0,a1,inv=(mod+1)/2;
for(ri mid=1;mid<lim;mid<<=1)for(ri j=0,len=mid<<1;j<lim;j+=len)
for(ri k=0;k<mid;++k){
a0=a[j+k],a1=a[j+k+mid];
a[j+k]=add(a0,a1),a[j+k+mid]=dec(a0,a1);
if(type==-1)a[j+k]=mul(a[j+k],inv),a[j+k+mid]=mul(a[j+k+mid],inv);
}
}
int main(){
n=read(),lim=1<<n;
for(ri i=0;i<lim;++i)a.push_back(read());
for(ri i=0;i<lim;++i)b.push_back(read());
c.resize(lim);
fmt(a,1),fmt(b,1);
for(ri i=0;i<lim;++i)c[i]=mul(a[i],b[i]);
fmt(c,-1),fmt(a,-1),fmt(b,-1);
for(ri i=0;i<lim;++i)cout<<c[i]<<' ';
puts("");
fwt_and(a,1),fwt_and(b,1);
for(ri i=0;i<lim;++i)c[i]=mul(a[i],b[i]);
fwt_and(c,-1),fwt_and(a,-1),fwt_and(b,-1);
for(ri i=0;i<lim;++i)cout<<c[i]<<' ';
puts("");
fwt_xor(a,1),fwt_xor(b,1);
for(ri i=0;i<lim;++i)c[i]=mul(a[i],b[i]);
fwt_xor(c,-1);
for(ri i=0;i<lim;++i)cout<<c[i]<<' ';
puts("");
return 0;
}