码迷,mamicode.com
首页 > 其他好文 > 详细

【模板】快速沃尔什变换

时间:2019-07-08 00:21:12      阅读:80      评论:0      收藏:0      [点我收藏+]

标签:fft   mes   amp   快速   重要   inline   cst   ++   printf   

基本思路和代码写起来与 \(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_0-A_1))\)

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("\n");
    
    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("\n");
    
    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("\n");
    
    return 0;
}

【模板】快速沃尔什变换

标签:fft   mes   amp   快速   重要   inline   cst   ++   printf   

原文地址:https://www.cnblogs.com/lindalee/p/11148499.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!