来自zyl https://dudulu.net/blog/?p=1705
int rev=mod+1>>1;
void FWT(ll a[],int n) //n必须为2的某次方
{
for(int d=1; d<n; d<<=1)
{
for(int m=d<<1,i=0; i<n; i+=m)
{
for(int j=0; j<d; j++)
{
int x=a[i+j],y=a[i+j+d];
a[i+j]=(x+y)%mod,a[i+j+d]=(x-y+mod)%mod;
//xor:a[i+j]=x+y,a[i+j+d]=(x-y+mod)%mod;
//and:a[i+j]=x+y;
//or:a[i+j+d]=x+y;
}
}
}
}
void UFWT(ll a[],int n)
{
for(int d=1; d<n; d<<=1)
{
for(int m=d<<1,i=0; i<n; i+=m)
{
for(int j=0; j<d; j++)
{
int x=a[i+j],y=a[i+j+d];
a[i+j]=1LL*(x+y)*rev%mod,a[i+j+d]=(1LL*(x-y)*rev%mod+mod)%mod;
//xor:a[i+j]=(x+y)/2,a[i+j+d]=(x-y)/2;
//and:a[i+j]=x-y;
//or:a[i+j+d]=y-x;
}
}
}
}
void solve(int a[],int b[],int n)
{
FWT(a,n);
FWT(b,n);
for(int i=0;i<n;i++) a[i]=1LL*a[i]*b[i]%mod;
UFWT(a,n);
}

1595

被折叠的 条评论
为什么被折叠?



