P4717 【模板】快速沃尔什变换
P4717 【模板】快速沃尔什变换
分析:
快速沃尔什变换模板题。
代码:
#include<cstdio> #include<algorithm> #include<iostream> #include<cstring> #include<cmath> #include<cctype> #include<set> #include<queue> #include<vector> #include<map> #include<bitset> using namespace std; typedef long long LL; inline int read() { int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1; for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f; } const int mod = 998244353, inv2 = 499122177, N = 131075; int A[N], B[N], C[N], ta[N], tb[N]; inline int add(int x,int y) { x += y; return x < 0 ? x + mod : (x >= mod ? x - mod : x); } inline int mul(int x,int y) { return 1ll * x * y % mod; } void fwtxor(int *a,int len,int ty) { for (int m = 2; m <= len; m <<=1) for (int i = 0; i < len; i += m) for (int k = 0; k < (m >> 1); ++k) { int x = a[i + k], y = a[i + k + (m >> 1)]; if (ty == 1) a[i + k] = add(x, y), a[i + k + (m >> 1)] = add(x, -y); else a[i + k] = mul(add(x, y), inv2), a[i + k + (m >> 1)] = mul(add(x, -y), inv2); } } void fwtor(int *a,int len,int ty) { for (int m = 2; m <= len; m <<= 1) for (int i = 0; i < len; i += m) for (int k = 0; k < (m >> 1); ++k) a[i + k + (m >> 1)] = add(ty * a[i + k], a[i + k + (m >> 1)]); } void fwtand(int *a,int len,int ty) { for (int m = 2; m <= len; m <<= 1) for (int i = 0; i < len; i += m) for (int k = 0; k < (m >> 1); ++k) a[i + k] = add(a[i + k], ty * a[i + k + (m >> 1)]); } int main() { int n = 1 << read(); for (int i = 0; i < n; ++i) A[i] = ta[i] = read(); for (int i = 0; i < n; ++i) B[i] = tb[i] = read(); fwtor(A, n, 1); fwtor(B, n, 1); for (int i = 0; i < n; ++i) C[i] = mul(A[i], B[i]); fwtor(C, n, -1); for (int i = 0; i < n; ++i) printf("%d ",C[i]); puts(""); // fwtor(A, n, -1); fwtor(B, n, -1); memcpy(A, ta, sizeof ta); memcpy(B, tb, sizeof tb); fwtand(A, n, 1); fwtand(B, n, 1); for (int i = 0; i < n; ++i) C[i] = mul(A[i], B[i]); fwtand(C, n, -1); for (int i = 0; i < n; ++i) printf("%d ",C[i]); puts(""); // fwtand(A, n, -1); fwtand(B, n, -1); memcpy(A, ta, sizeof ta); memcpy(B, tb, sizeof tb); fwtxor(A, n, 1); fwtxor(B, n, 1); for (int i = 0; i < n; ++i) C[i] = mul(A[i], B[i]); fwtxor(C, n, -1); for (int i = 0; i < n; ++i) printf("%d ",C[i]); return 0; }