pre:
http://www.cnblogs.com/zwfymqz/p/8244902.html
(思路与后续不同,思考如何和后续统一)
以一种高度思考
http://picks.logdown.com/posts/179290-fast-walsh-hadamard-transform
完善
https://blog.youkuaiyun.com/zhshrs/article/details/54838466
代码参考
https://blog.youkuaiyun.com/john123741/article/details/76576925
P.S.:
FFT和FWT,两者虽然某些原理(两分,使用重复项来降低时间复杂度)相似,但是,两个算法风马牛不相及!
快速莫比乌斯变换
study from :
https://yhx-12243.github.io/OI-transit/records/vijos%20%234.html
适用于and or,xor 行不通
FMT写法和FWT是一样的,两者考虑问题角度不一样。
存储函数地址
void (*addr1[3])(ll a[])={fwt1,fwt2,fwt3};
void (*addr2[3])(ll a[])={ufwt1,ufwt2,ufwt3};
https://www.luogu.org/problemnew/show/P4717
1 #include <cstdio> 2 using namespace std; 3 4 #define ll long long 5 const int maxn=1<<17; 6 const ll mod=998244353; 7 const ll inv2=(mod+1)/2; 8 9 ll a[maxn],b[maxn],x[maxn],y[maxn]; 10 int w,n; 11 12 ///or 13 void fwt1(ll a[]) 14 { 15 int i,j,k,l; 16 for (i=2,l=1;i<=n;i<<=1,l<<=1) ///range 17 for (j=0;j<n;j+=i) ///begin_index 18 for (k=j;k<j+l;k++) ///index 19 a[k+l]=(a[k+l]+a[k])%mod; 20 } 21 22 void ufwt1(ll a[]) 23 { 24 int i,j,k,l; 25 for (i=2,l=1;i<=n;i<<=1,l<<=1) ///range 26 for (j=0;j<n;j+=i) ///begin_index 27 for (k=j;k<j+l;k++) ///index 28 a[k+l]=(a[k+l]-a[k])%mod; 29 } 30 31 ///and 32 void fwt2(ll a[]) 33 { 34 int i,j,k,l; 35 for (i=2,l=1;i<=n;i<<=1,l<<=1) ///range 36 for (j=0;j<n;j+=i) ///begin_index 37 for (k=j;k<j+l;k++) ///index 38 a[k]=(a[k]+a[k+l])%mod; 39 } 40 41 void ufwt2(ll a[]) 42 { 43 int i,j,k,l; 44 for (i=2,l=1;i<=n;i<<=1,l<<=1) ///range 45 for (j=0;j<n;j+=i) ///begin_index 46 for (k=j;k<j+l;k++) ///index 47 a[k]=(a[k]-a[k+l])%mod; 48 } 49 50 ///xor 51 void fwt3(ll a[]) 52 { 53 int i,j,k,l; 54 ll m; 55 for (i=2,l=1;i<=n;i<<=1,l<<=1) ///range 56 for (j=0;j<n;j+=i) ///begin_index 57 for (k=j;k<j+l;k++) ///index 58 { 59 m=a[k]; 60 a[k]=(a[k]+a[k+l])%mod; 61 a[k+l]=(m-a[k+l])%mod; 62 } 63 } 64 65 void ufwt3(ll a[]) 66 { 67 int i,j,k,l; 68 ll m; 69 for (i=2,l=1;i<=n;i<<=1,l<<=1) ///range 70 for (j=0;j<n;j+=i) ///begin_index 71 for (k=j;k<j+l;k++) ///index 72 { 73 m=a[k]; 74 a[k]=(a[k]+a[k+l])*inv2%mod;/// /2 75 a[k+l]=(m-a[k+l])*inv2%mod; /// /2 76 } 77 } 78 79 void init() 80 { 81 int i; 82 for (i=0;i<n;i++) 83 a[i]=x[i],b[i]=y[i]; 84 } 85 86 void cal() 87 { 88 int i; 89 for (i=0;i<n;i++) 90 a[i]=a[i]*b[i]%mod; 91 } 92 93 void print() 94 { 95 int i; 96 for (i=0;i<n;i++) 97 printf("%lld%c",(a[i]+mod)%mod,i==n-1?'\n':' '); 98 } 99 100 int main() 101 { 102 int i; 103 scanf("%d",&w); 104 n=1<<w; 105 for (i=0;i<n;i++) 106 scanf("%lld",&x[i]); 107 for (i=0;i<n;i++) 108 scanf("%lld",&y[i]); 109 110 void (*addr1[3])(ll a[])={fwt1,fwt2,fwt3}; 111 void (*addr2[3])(ll a[])={ufwt1,ufwt2,ufwt3}; 112 for (i=0;i<3;i++) 113 { 114 init(); 115 (*addr1[i])(a); 116 (*addr1[i])(b); 117 cal(); 118 (*addr2[i])(a); 119 print(); 120 } 121 return 0; 122 }