FWT快速沃尔什变换

Fast Walsh-Hadamard Transform 就是用于解决一类卷积问题的方法。

时间复杂度nlogn,求解的内容如下
FWT快速沃尔什变换_第1张图片

可以用于求解数组A和数组B异或后能得到哪些数之类的问题(暴力枚举是n2的复杂度)

void FWT(int a[],int n)  
{  
    for(int d=1;d1)  
        for(int m=d<<1,i=0;ifor(int j=0;jint 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(int a[],int n)  
{  
    for(int d=1;d1){
        for(int m=d<<1,i=0;ifor(int j=0;jint 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)  
{  
    //求解C[i]=segma(j^k==i?a[j]*b[k]:0),时间复杂度nlogn 
    //可用于求解n个数两两异或能得到哪些数,c[i]!=0表示该数能求解得到。
    FWT(a,n);  
    FWT(b,n);  
    for(int i=0;i1LL*a[i]*b[i]%mod;  
    UFWT(a,n);  
}

你可能感兴趣的:(模板)