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
",_Mavis);
}
View Code
原文地址:https://www.cnblogs.com/Enceladus/p/7102038.html