zoukankan      html  css  js  c++  java
  • 【模板】快速沃尔什变换

    基本思路和代码写起来与 (FFT) 都极像。
    比较重要的几个式子:

    or卷积

    (FWT(A_0,A_1)=(FWT(A_0),FWT(A_0+A_1)))
    (IFWT(A_0,A_1)=(IFWT(A_0),IFWT(A_1-A_0)))

    and卷积

    (FWT(A_0,A_1)=(FWT(A_0+A_1),FWT(A_1)))
    (IFWT(A_0,A_1)=(IFWT(A_0-A_1),IFWT(A_1)))

    xor卷积

    (FWT(A_0,A_1)=(FWT(A_0+A_1),FWT(A_0-A_1)))
    (IFWT(A_0,A_1)=(frac{IFWT(A_0+A_1)}{2},frac{IFWT(A_0-A_1)}{2}))


    一点想法

    主要是今天模拟赛是第一题是 (FWTxor)(wzj) 学长说是用来练手,但我实在都不知道它是干啥的【捂脸】
    搞了一晚上,差不多知道是干什么的了,但有些细节还没太透彻,还要继续研究~
    搞出了代码!看着很简洁~


    代码

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    
    #define P 998244353
    #define xzy 499122177
    
    using namespace std;
    
    const int N = 1<<17;
    typedef long long ll; 
    
    int n,a[N],b[N],c[N],d[N];
    void fwt_or(int *A,int ty){
    	for(int i=2;i<=n;i<<=1)
    		for(int j=0;j<n;j+=i)
    			for(int k=j;k<j+i/2;k++)
    				A[k+i/2]=((ll)A[k+i/2]+A[k]*ty+P)%P;
    }
    void fwt_and(int *A,int ty){
    	for(int i=2;i<=n;i<<=1)
    		for(int j=0;j<n;j+=i)
    			for(int k=j;k<j+i/2;k++)
    				A[k]=((ll)A[k]+A[k+i/2]*ty+P)%P; 
    }
    void fwt_xor(int *A,int ty){
    	for(int i=2;i<=n;i<<=1)
    		for(int j=0;j<n;j+=i)
    			for(int k=j;k<j+i/2;k++){
    				int t=A[k+i/2];
    				A[k+i/2]=(A[k]-t+P)%P;
    				A[k]=(A[k]+t)%P;
    				if(ty==-1) {
    					A[k+i/2]=1ll*A[k+i/2]*xzy%P;
    					A[k]=1ll*A[k]*xzy%P;
    				}
    			}
    }
    
    int main()
    {
    	scanf("%d",&n);
    	n=1<<n;
    	for(int i=0;i<n;i++)
    		scanf("%d",&a[i]);
    	for(int i=0;i<n;i++)
    		scanf("%d",&b[i]);
    	
    	for(int i=0;i<n;i++) c[i]=a[i],d[i]=b[i];
    	fwt_or(c,1); fwt_or(d,1);
    	for(int i=0;i<n;i++) c[i]=1ll*c[i]*d[i]%P;
    	fwt_or(c,-1);
    	for(int i=0;i<n;i++) printf("%d ",c[i]);printf("
    ");
    	
    	for(int i=0;i<n;i++) c[i]=a[i],d[i]=b[i];
    	fwt_and(c,1); fwt_and(d,1);
    	for(int i=0;i<n;i++) c[i]=1ll*c[i]*d[i]%P;
    	fwt_and(c,-1);
    	for(int i=0;i<n;i++) printf("%d ",c[i]);printf("
    ");
    	
    	for(int i=0;i<n;i++) c[i]=a[i],d[i]=b[i];
    	fwt_xor(c,1); fwt_xor(d,1);
    	for(int i=0;i<n;i++) c[i]=1ll*c[i]*d[i]%P;
    	fwt_xor(c,-1);
    	for(int i=0;i<n;i++) printf("%d ",c[i]);printf("
    ");
    	
    	return 0;
    }
    
    既然选择了远方,便只顾风雨兼程
  • 相关阅读:
    mysql root密码重置
    fetch跨域问题
    HTML5触摸事件(touchstart、touchmove和touchend)
    react-router-dom
    清理网站缓存
    从零开始学java (标识符,关键字,基本数据类型)
    从零开始学java ( 初始java)
    入职一年心得
    guava 函数式编程三兄弟
    java读取各种类型文件
  • 原文地址:https://www.cnblogs.com/lindalee/p/11148499.html
Copyright © 2011-2022 走看看