题解 P6097 【【模板】子集卷积】
EternalAlexander · · 题解
记
第一个限制
考虑第二个限制
具体地,令
复杂度
#include <bits/stdc++.h>
#define ll long long
const int mod=1e9+9;
int a[22][1<<21],b[22][1<<21],h[22][1<<21],n,t;
int ctz(int x){return __builtin_popcount(x);}
void fwt(int *a,int n,int flag){
for(int i=1;i<n;i<<=1)
for(int len=i<<1,j=0;j<n;j+=len)
for(int k=0;k<i;++k){
if (flag==1)a[j+k+i]=(a[j+k]+a[j+k+i])%mod;
else a[j+k+i]=(a[j+k+i]-a[j+k]+mod)%mod;
}
}
int main(){
scanf("%d",&n);
int lim=n;n=1<<n;
for(int i=0;i<n;++i)
scanf("%d",&a[ctz(i)][i]);
for(int i=0;i<n;++i)
scanf("%d",&b[ctz(i)][i]);
for(int i=0;i<=lim;++i){
fwt(a[i],n,1);fwt(b[i],n,1);
}for(int i=0;i<=lim;++i)
for(int j=0;j<=i;++j)
for(int k=0;k<n;++k)h[i][k]=(h[i][k]+(ll)a[j][k]*b[i-j][k]%mod)%mod;
for(int i=0;i<=lim;++i)fwt(h[i],n,-1);
for(int i=0;i<n;++i)printf("%d ",h[ctz(i)][i]);
return 0;
}