FWT板子

#include<bits/stdc++.h>
#define ll long long
#define R register
template<class T>
void rea(T &x)
{
	int f(0);char ch=getchar();x = 0;
	while(!isdigit(ch)){f|=ch=='-';ch=getchar();}
	while(isdigit(ch)){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
	x = f?-x:x;
}
using namespace std;
const int N = (1<<17)+5;
const int mod = 998244353, inv2 = 499122177;
int a[N], b[N], c[N], limit;
void FWTand(int *a, int flag)
{
	for(R int len = 2; len <= limit; len *= 2)
		for(R int i = 0, mid = len>>1; i < limit; i += len)
			for(R int j = i; j < i+mid; ++j)
				a[j] = (a[j]+a[j+mid]*flag+(flag==1?0:mod))%mod;
}
void FWTor(int *a, int flag)
{
	for(R int len = 2; len <= limit; len *= 2)
		for(R int i = 0, mid = len>>1; i < limit; i += len)
			for(R int j = i; j < i+mid; ++j)
				a[j+mid] = (a[j+mid]+a[j]*flag+(flag==1?0:mod))%mod;
}
void FWTxor(int *a, int flag)
{
	for(R int len = 2; len <= limit; len *= 2)
		for(R int i = 0, mid = len>>1; i < limit; i += len)
			for(R int j = i; j < i+mid; ++j)
			{
				int x = a[j], y = a[j+mid];
				a[j] = (x+y)%mod, a[j+mid] = (x-y+mod)%mod;
				if(flag == -1) a[j] = (1ll*a[j]*inv2)%mod, a[j+mid] = (1ll*a[j+mid]*inv2)%mod;
			}
} 
int main()
{
	int n;
	rea(n); limit = (1<<n);
	for(R int i = 0; i < limit; ++i) rea(a[i]);
	for(R int i = 0; i < limit; ++i) rea(b[i]);
	FWTor(a, 1), FWTor(b, 1);
	for(R int i = 0; i < limit; ++i) c[i] = (1ll*a[i]*b[i])%mod;
	FWTor(a, -1), FWTor(b, -1), FWTor(c, -1);
	for(R int i = 0; i < limit; ++i) printf("%d ", c[i]); printf("
");
	FWTand(a, 1), FWTand(b, 1);
	for(R int i = 0; i < limit; ++i) c[i] = (1ll*a[i]*b[i])%mod;
	FWTand(a, -1), FWTand(b, -1), FWTand(c, -1);
	for(R int i = 0; i < limit; ++i) printf("%d ", c[i]); printf("
");
	FWTxor(a, 1), FWTxor(b, 1);
	for(R int i = 0; i < limit; ++i) c[i] = (1ll*a[i]*b[i])%mod;
	FWTxor(a, -1), FWTxor(b, -1), FWTxor(c, -1);
	for(R int i = 0; i < limit; ++i) printf("%d ", c[i]); printf("
");
    return 0;
}

原文地址:https://www.cnblogs.com/heanda/p/12494854.html