zoukankan      html  css  js  c++  java
  • 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;
    }
    
    
  • 相关阅读:
    MySQL锁系列3 MDL锁
    MySQL锁系列2 表锁
    MySQL锁系列1
    MySQL open table
    MySQL优化器join顺序
    MySQL优化器cost计算
    MySQL源码 优化器
    MySQL源码 解析器
    MySQL源码 数据结构hash
    微信小程序爬坑日记
  • 原文地址:https://www.cnblogs.com/With-penguin/p/13442135.html
Copyright © 2011-2022 走看看