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); }
以上是关于FWT模板的主要内容,如果未能解决你的问题,请参考以下文章