FWT模板

Posted Swm_sxt

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了FWT模板相关的知识,希望对你有一定的参考价值。

 

代码来自51nod1570

技术分享
#include<cstdio>
#include<cstring>
#include<algorithm>
#define MN 501
using namespace std;

int read_p,read_ca;
inline int read(){
    read_p=0;read_ca=getchar();
    while(read_ca<0||read_ca>9) read_ca=getchar();
    while(read_ca>=0&&read_ca<=9) read_p=read_p*10+read_ca-48,read_ca=getchar();
    return read_p;
}
const int MOD=1e9+7,N2=(MOD+1)/2;
int n,m,MMH=0,Mavis=0,_Mavis=0,mmh[MN][(1<<16)+1],ro,num=0,a[(1<<16)+1],b[(1<<16)+1];
char s[MN];
inline void M(int &x){while(x>=MOD)x-=MOD;while(x<0)x+=MOD;}
void work(int p,bool b,int mmh[]){
    int s=0;
    for (int i=0;i<16;i++) s|=(((i>>p)&1)^b)<<i;
    mmh[s]++;
}
inline void FWT_x(int N,int a[]){
    for (int i=2;i<=N;i<<=1)
    for (int m=i>>1,j=0;j<N;j+=i)
    for (int k=0;k<m;k++) M(a[j+k]+=a[j+k+m]),M(a[j+k+m]=a[j+k]-2*a[j+k+m]);
}
inline void IFWT_x(int N,int a[]){
    for (int i=2;i<=N;i<<=1)
    for (int m=i>>1,j=0;j<N;j+=i)
    for (int k=0;k<m;k++){
        int A=a[j+k],B=a[j+k+m];
        a[j+k]=1LL*(A+B)*N2%MOD;
        a[j+k+m]=1LL*(A+MOD-B)*N2%MOD;
    }
}
inline void FWT_a(int N,int a[]){
    for (int i=2;i<=N;i<<=1)
    for (int m=i>>1,j=0;j<N;j+=i)
    for (int k=0;k<m;k++) M(a[j+k]+=a[j+k+m]);
}
inline void IFWT_a(int N,int a[]){
    for (int i=2;i<=N;i<<=1)
    for (int m=i>>1,j=0;j<N;j+=i)
    for (int k=0;k<m;k++) M(a[j+k]-=a[j+k+m]);
}
inline void FWT_o(int N,int a[]){
    for (int i=2;i<=N;i<<=1)
    for (int m=i>>1,j=0;j<N;j+=i)
    for (int k=0;k<m;k++) M(a[j+k+m]+=a[j+k]);
}
inline void IFWT_o(int N,int a[]){
    for (int i=2;i<=N;i<<=1)
    for (int m=i>>1,j=0;j<N;j+=i)
    for (int k=0;k<m;k++) M(a[j+k+m]-=a[j+k]);
}
void hb(int A[],int B[],int mmh[],bool kind){
    for (int i=0;i<(1<<16);i++) a[i]=A[i],b[i]=B[i];
    if (kind){
        FWT_o(1<<16,a);FWT_o(1<<16,b);
        for (int i=0;i<(1<<16);i++) a[i]=1LL*a[i]*b[i]%MOD;
        IFWT_o(1<<16,a);
        for (int i=0;i<(1<<16);i++) M(mmh[i]+=a[i]);
    }else{
        FWT_a(1<<16,a);FWT_a(1<<16,b);
        for (int i=0;i<(1<<16);i++) a[i]=1LL*a[i]*b[i]%MOD;
        IFWT_a(1<<16,a);
        for (int i=0;i<(1<<16);i++) M(mmh[i]+=a[i]);
    }
}
int work(int l,int r){
    int p=++num,i,j;
    if (l==r){
        if (s[l]==?) for (i=0;i<4;i++) work(i,0,mmh[p]),work(i,1,mmh[p]);else
        if (s[l]==A) work(0,0,mmh[p]);else
        if (s[l]==a) work(0,1,mmh[p]);else
        if (s[l]==B) work(1,0,mmh[p]);else
        if (s[l]==b) work(1,1,mmh[p]);else
        if (s[l]==C) work(2,0,mmh[p]);else
        if (s[l]==c) work(2,1,mmh[p]);else
        if (s[l]==D) work(3,0,mmh[p]);else
        if (s[l]==d) work(3,1,mmh[p]);
    }else{
        for (i=l,j=0;;i++)
        if (j+=s[i]==(,j-=s[i]==),!j) break;
        i++;
        int L=work(l+1,i-2),R=work(i+2,r-1);
        if (s[i]==&) hb(mmh[L],mmh[R],mmh[p],0);else
        if (s[i]==|) hb(mmh[L],mmh[R],mmh[p],1);else
        hb(mmh[L],mmh[R],mmh[p],0),hb(mmh[L],mmh[R],mmh[p],1);
    }
    return p;
}
int main(){
    scanf("%s",s);
    ro=work(0,strlen(s)-1);
    n=read();
    for (int i=1;i<=n;i++){
        int a=0;
        a|=read();a|=read()<<1;a|=read()<<2;a|=read()<<3;
        MMH|=1<<a;Mavis|=read()<<a;
    }
    for (int i=0;i<(1<<16);i++)
    if (!((i^Mavis)&MMH)) (_Mavis+=mmh[ro][i])%=MOD;
    printf("%d\n",_Mavis);
}
View Code

 

以上是关于FWT模板的主要内容,如果未能解决你的问题,请参考以下文章

洛谷 - P4717 模板快速莫比乌斯/沃尔什变换 (FMT/FWT)

FWT模板

FWT模板

FWT模板

2023.4.7模板快速沃尔什变换FWT

Luogu4717 模板快速沃尔什变换(FWT)