• 【知识点】FWT


    or卷积:

    大概是给定多项式A,B,求多项式C满足$C(x)=sum limits_{i|j=x}{A(i) imes B(j)}$。

    仔细思考一下,我们可以将A,B分别做一个子集和,然后对位相乘。

    那么乘得的多项式F便满足$F(x)=sum limits_{i|jsubseteq x}{A(i) imes B(j)}$。

    然后我们对F做一个子集差($F(x)=F(x)-sum limits_{isubset x}{F(i)}$),最后得到的就是多项式C。

    如果按FFT的写法,那么DFT就是子集和,IDFT就是子集差。(不过这个做法跟FFT并没有很强的联系)

    and卷积:

    把上文所有的子集改成超集。

    xor卷积:

    唯一一个不一样的。

    我们设$bits(x)$表示x的二进制中1个数的奇偶性。

    那么有$bits(i& x)oplus bits(j& x)=bits((ioplus j)& x)$。(将其拆成若干个1xor之和即可证明)

    考虑构造$A'(x)=sum limits_{i=0}^{2^{n}-1}{(-1)^{bits(i& x)}A(i)}$

    那么$A'(x) imes B'(x)=sum limits_{i=0}^{2^{n}-1}{(-1)^{bits(i& x)}A(i)} imes sum limits_{j=0}^{2^{n}-1}{(-1)^{bits(j& x)}B(j)}$

    $=sum limits_{i=0}^{2^{n}-1}{sum limits_{j=0}^{2^{n}-1}{(-1)^{bits((ioplus j)& x)}A(i) imes B(j)}}$

    $=C'(x)$

    于是就可以了,这构造我也不知道是怎么想到的。

    DFT的时候按二进制第i位01分组,加一下0对0,0对1,1对0,1对1的贡献,代码看起来基本就是w=1的FFT。

    IDFT的时候相当于已知x+y,x-y,让你求x,y。直接算就行。

    代码:

    #include<bits/stdc++.h>
    #define maxn 1000005
    #define maxm 500005
    #define inf 0x7fffffff
    #define mod 998244353
    #define ll long long
    #define rint register ll
    #define debug(x) cerr<<#x<<": "<<x<<endl
    #define fgx cerr<<"--------------"<<endl
    #define dgx cerr<<"=============="<<endl
    
    using namespace std;
    ll n,m,F[maxn],G[maxn],A[maxn],B[maxn],C[maxn];
    
    inline ll read(){
        ll x=0,f=1; char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
        for(;isdigit(c);c=getchar()) x=x*10+c-'0';
        return x*f;
    }
    
    inline void fwt_or(ll *a,ll op){
        for(ll l=2;l<=n;l<<=1)
            for(ll i=0;i<n;i+=l)
                for(ll j=i;j<i+(l>>1);j++)
                    a[j+(l>>1)]=(a[j+(l>>1)]+op*a[j]+mod)%mod;
    }
    
    inline void fwt_and(ll *a,ll op){
        for(ll l=2;l<=n;l<<=1)
            for(ll i=0;i<n;i+=l)
                for(ll j=i;j<i+(l>>1);j++)
                    a[j]=(a[j]+op*a[j+(l>>1)]+mod)%mod;
    }
    
    inline void fwt_xor(ll *a,ll op){
        ll inv=(mod+1)>>1;
        for(ll l=2;l<=n;l<<=1)
            for(ll i=0;i<n;i+=l)
                for(ll j=i;j<i+(l>>1);j++){
                    ll x=a[j],y=a[j+(l>>1)];
                    a[j]=(x+y)%mod,a[j+(l>>1)]=(x-y+mod)%mod;
                    if(op==-1) a[j]=a[j]*inv%mod,a[j+(l>>1)]=a[j+(l>>1)]*inv%mod;    
                }
    }
    
    int main(){
        m=read(),n=1<<m;
        for(ll i=0;i<n;i++) F[i]=read();
        for(ll i=0;i<n;i++) G[i]=read();
        memcpy(A,F,sizeof(F));
        memcpy(B,G,sizeof(G));
        fwt_or(A,1),fwt_or(B,1);
        for(ll i=0;i<n;i++) C[i]=A[i]*B[i]%mod;
        fwt_or(C,-1);
        for(ll i=0;i<n;i++) printf("%lld ",C[i]); 
        printf("
    ");
        memcpy(A,F,sizeof(F));
        memcpy(B,G,sizeof(G));
        fwt_and(A,1),fwt_and(B,1);
        for(ll i=0;i<n;i++) C[i]=A[i]*B[i]%mod;
        fwt_and(C,-1);
        for(ll i=0;i<n;i++) printf("%lld ",C[i]); 
        printf("
    ");
        memcpy(A,F,sizeof(F));
        memcpy(B,G,sizeof(G));
        fwt_xor(A,1),fwt_xor(B,1);
        for(ll i=0;i<n;i++) C[i]=A[i]*B[i]%mod;
        fwt_xor(C,-1);
        for(ll i=0;i<n;i++) printf("%lld ",C[i]); 
        printf("
    ");
        return 0;
    }
    FWT
  • 相关阅读:
    最大似然估计
    信号和槽:Qt中最差劲的创造
    从生物神经网络到人工神经网络
    巩固一下C语言中的指针
    linux启动后自动登录并运行自定义图形界面程序
    删除linux系统服务
    《痞子衡嵌入式半月刊》 索引
    痞子衡嵌入式:恩智浦i.MX RTxxx系列MCU开发那些事
    痞子衡嵌入式:高性能MCU之音视频应用开发那些事
    痞子衡嵌入式:恩智浦i.MX RT1xxx系列MCU开发那些事
  • 原文地址:https://www.cnblogs.com/YSFAC/p/13059823.html
Copyright © 2020-2023  润新知