luogu P4717 【模板】快速沃尔什变换 (FWT)

代码:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#define int long long

using namespace std;

const int N=1000000,M=998244353;
int A[N],B[N],tmp_A[N],tmp_B[N],n,inv2;

int ksm(int a,int b)
{
	int res=1;
	while(b)
	{
		if(b&1)
			res=res*a%M;
		b>>=1,a=a*a%M;
	}
	return res;
}

void init()
{
	scanf("%lld",&n);
	n=1<<n;
	for (int i=0;i<n;i++)
		scanf("%lld",&tmp_A[i]);
	for (int i=0;i<n;i++)
		scanf("%lld",&tmp_B[i]);
	inv2=ksm(2,M-2);
}

void fwt_or(int A[],int flag)
{
	for (int l=1;l<n;l<<=1)
		for (int i=0;i<n;i+=l<<1)
			for (int j=0;j<l;j++)
			{
				int u=A[i+j],v=A[i+j+l];
				if(flag==1)
					A[i+j]=u,A[i+j+l]=(u+v)%M;
				else
					A[i+j]=u,A[i+j+l]=(v-u)%M;
			}
}

void FWT_OR()
{
	for (int i=0;i<n;i++)
		A[i]=tmp_A[i],B[i]=tmp_B[i];
	fwt_or(A,1),fwt_or(B,1);
	for (int i=0;i<n;i++)
		A[i]=A[i]*B[i]%M;
	fwt_or(A,-1);
	for (int i=0;i<n;i++)
		printf("%lld ",(A[i]+M)%M);puts("");
}

void fwt_and(int A[],int flag)
{
	for (int l=1;l<n;l<<=1)
		for (int i=0;i<n;i+=l<<1)
			for (int j=0;j<l;j++)
			{
				int u=A[i+j],v=A[i+j+l];
				if(flag==1)
					A[i+j]=(u+v)%M,A[i+j+l]=v;
				else
					A[i+j]=(u-v)%M,A[i+j+l]=v;
			}
}

void FWT_AND()
{
	for (int i=0;i<n;i++)
		A[i]=tmp_A[i],B[i]=tmp_B[i];
	fwt_and(A,1),fwt_and(B,1);
	for (int i=0;i<n;i++)
		A[i]=A[i]*B[i]%M;
	fwt_and(A,-1);
	for (int i=0;i<n;i++)
		printf("%lld ",(A[i]+M)%M);puts("");
}

void fwt_xor(int A[],int flag)
{
	for (int l=1;l<n;l<<=1)
		for (int i=0;i<n;i+=l<<1)
			for (int j=0;j<l;j++)
			{
				int u=A[i+j],v=A[i+j+l];
				if(flag==1)
					A[i+j]=(u+v)%M,A[i+j+l]=(u-v)%M;
				else
					A[i+j]=(u+v)%M*inv2%M,A[i+j+l]=(u-v)%M*inv2%M;
			}
}

void FWT_XOR()
{
	for (int i=0;i<n;i++)
		A[i]=tmp_A[i],B[i]=tmp_B[i];
	fwt_xor(A,1),fwt_xor(B,1);
	for (int i=0;i<n;i++)
		A[i]=A[i]*B[i]%M;
	fwt_xor(A,-1);
	for (int i=0;i<n;i++)
		printf("%lld ",(A[i]+M)%M);puts("");
}

void work()
{
	FWT_OR(),FWT_AND(),FWT_XOR();
}

signed main()
{
//	freopen("P4717.in","r",stdin);
//	freopen("P4717.out","w",stdout);
	init();
	work();
	return 0;
}

posted @   With_penguin  阅读(84)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示