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;
}
原文地址:https://www.cnblogs.com/mjtcn/p/10569905.html