ANJHZ的博客

2021.08.15 FWT快速沃尔什变换

先把模板代码贴在这,其他的明天再写)

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+11;
const long long mo=998244353;
int n,m;
ll a[N],b[N],c[N],inv2;
ll quickpow(ll now,ll mi)
{
    ll re=1;
    while(mi)
    {
        if(mi&1) re=(re*now)%mo;
        now=(now*now)%mo;mi>>=1;
    }
    return re;
}
void fwt_or(ll* t,int len,ll f)
{
    ll x,y;
    for(int midlen=1;midlen<len;midlen<<=1)
    {
        for(int st=0;st<len;st+=(midlen<<1))
        {
            for(int i=0;i<midlen;i++)
            {
                x=t[st+i];y=t[st+i+midlen];
                t[st+i]=x%mo;
                t[st+i+midlen]=((f*x+y)%mo+mo)%mo;
            }
        }
    }
}
void fwt_and(ll* t,int len,ll f)
{
    ll x,y;
    for(int midlen=1;midlen<len;midlen<<=1)
    {
        for(int st=0;st<len;st+=(midlen<<1))
        {
            for(int i=0;i<midlen;i++)
            {
                x=t[st+i];y=t[st+i+midlen];
                t[st+i]=((x+f*y)%mo+mo)%mo;
                t[st+i+midlen]=y%mo;
            }
        }
    }
}
void fwt_xor(ll* t,int len,ll f)
{
    ll x,y;
    for(int midlen=1;midlen<len;midlen<<=1)
    {
        for(int st=0;st<len;st+=(midlen<<1))
        {
            for(int i=0;i<midlen;i++)
            {
                x=t[st+i];y=t[st+i+midlen];
                t[st+i]=(x+y)%mo;
                t[st+i+midlen]=(x-y+mo)%mo;
                if(f==-1) t[st+i]=(t[st+i]*inv2)%mo,t[st+i+midlen]=(t[st+i+midlen]*inv2)%mo;
            }
        }
    }
}
int main()
{
    inv2=quickpow(2,mo-2);
    scanf("%d",&m);
    n=(1<<m);
    for(int i=0;i<n;i++) scanf("%lld",&a[i]);
    for(int i=0;i<n;i++) scanf("%lld",&b[i]);
    
    fwt_or(a,n,1);fwt_or(b,n,1);
    for(int i=0;i<n;i++) c[i]=(a[i]*b[i])%mo;
    fwt_or(c,n,-1);
    for(int i=0;i<n;i++) printf("%lld ",c[i]);
    printf("\n");
    fwt_or(a,n,-1);fwt_or(b,n,-1);
    
    fwt_and(a,n,1);fwt_and(b,n,1);
    for(int i=0;i<n;i++) c[i]=(a[i]*b[i])%mo;
    fwt_and(c,n,-1);
    for(int i=0;i<n;i++) printf("%lld ",c[i]);
    printf("\n");
    fwt_and(a,n,-1);fwt_and(b,n,-1);
    
    fwt_xor(a,n,1);fwt_xor(b,n,1);
    for(int i=0;i<n;i++) c[i]=(a[i]*b[i])%mo;
    fwt_xor(c,n,-1);
    for(int i=0;i<n;i++) printf("%lld ",c[i]);
    printf("\n");

    return 0;
} 

 

  

posted on 2021-08-15 23:24  ANJHZ  阅读(62)  评论(0)    收藏  举报

导航