Fast Walsh-Hadamard Transform 就是用于解决一类卷积问题的方法。
时间复杂度nlogn,求解的内容如下
可以用于求解数组A和数组B异或后能得到哪些数之类的问题(暴力枚举是n^2的复杂度)
1 void FWT(int a[],int n) 2 { 3 for(int d=1;d<n;d<<=1) 4 for(int m=d<<1,i=0;i<n;i+=m) 5 for(int j=0;j<d;j++) 6 { 7 int x=a[i+j],y=a[i+j+d]; 8 //a[i+j]=(x+y)%mod,a[i+j+d]=(x-y+mod)%mod; 9 //xor: 10 a[i+j]=x+y,a[i+j+d]=(x-y+mod)%mod; 11 //and:a[i+j]=x+y; 12 //or:a[i+j+d]=x+y; 13 } 14 } 15 16 void UFWT(int a[],int n) 17 { 18 for(int d=1;d<n;d<<=1){ 19 for(int m=d<<1,i=0;i<n;i+=m) { 20 for(int j=0;j<d;j++) 21 { 22 int x=a[i+j],y=a[i+j+d]; 23 //a[i+j]=1LL*(x+y)*rev%mod,a[i+j+d]=(1LL*(x-y)*rev%mod+mod)%mod; 24 //xor: 25 a[i+j]=(x+y)/2,a[i+j+d]=(x-y)/2; 26 //and:a[i+j]=x-y; 27 //or:a[i+j+d]=y-x; 28 } 29 } 30 } 31 32 } 33 void solve(int a[],int b[],int n) 34 { 35 //求解C[i]=segma(j^k==i?a[j]*b[k]:0),时间复杂度nlogn 36 //可用于求解n个数两两异或能得到哪些数,c[i]!=0表示该数能求解得到。 37 FWT(a,n); 38 FWT(b,n); 39 for(int i=0;i<n;i++) a[i]=1LL*a[i]*b[i]%mod; 40 UFWT(a,n); 41 }