• 快速沃尔什变换


    快速沃尔什变换

    题目背景

    模板题,无背景

    题目描述

    给定长度为(2^n)两个序列(A,B),设(C_i=sum_{joplus k=i}A_jB_k) 分别当(oplus)or,and,xor时求出(C)

    输入输出格式

    输入格式:

    第一行一个数(n)。 第二行(2^n)个数(A_0..A_{2^n-1}) 第三行(2^n)个数(B_0..B_{2^n-1})

    输出格式:

    三行每行(2^n)个数,分别代表(oplus)or,and,xor(C_0..C_{2^n-1})的值(mod 998244353)

    说明

    (nle 17)


    证明没怎么看懂,放结论了。

    or

    [FWT(A)=(FWT(A_0),FWT(A_0+A_1)) ]

    [IFWT(A)=(IFWT(A_0),IFWT(A_1-A_0)) ]

    and

    [FWT(A)=(FWT(A_0+A_1),FWT(A_1)) ]

    [IFWT(A)=(IFWT(A_0-A_1),IFWT(A_1)) ]

    xor

    [FWT(A)=(FWT(A_0+A_1),FWT(A_0-A_1)) ]

    [IFWT(A)=(IFWT(A_0+A_1)/2,IFWT(A_1-A_0)/2) ]

    背下来吧,像(FFT)那样写就好了


    Code:

    #include <cstdio>
    const int N=(1<<17)+10;
    const int mod=998244353,inv=499122177;
    int A[N],B[N],a[N],b[N],n,len;
    #define add(a,b) ((a+b)%mod)
    #define mul(a,b) (1ll*(a)*(b)%mod)
    void orfwt(int *a,int typ)
    {
        for(int le=1;le<len;le<<=1)
            for(int p=0;p<len;p+=le<<1)
                for(int i=p+le;i<p+(le<<1);i++)
                    if(typ) a[i]=add(a[i],a[i-le]);
                    else a[i]=add(a[i],mod-a[i-le]);
    }
    void andfwt(int *a,int typ)
    {
        for(int le=1;le<len;le<<=1)
            for(int p=0;p<len;p+=le<<1)
                for(int i=p;i<p+le;i++)
                    if(typ) a[i]=add(a[i],a[i+le]);
                    else a[i]=add(a[i],mod-a[i+le]);
    }
    void xorfwt(int *a,int typ)
    {
        for(int le=1;le<len;le<<=1)
            for(int p=0;p<len;p+=le<<1)
                for(int i=p;i<p+le;i++)
                {
                    int tx=a[i],ty=a[i+le];
                    a[i]=add(tx,ty),a[i+le]=add(tx,mod-ty);
                    if(!typ) a[i]=mul(a[i],inv),a[i+le]=mul(a[i+le],inv);
                }
    }
    int main()
    {
        scanf("%d",&n);len=1<<n;
        for(int i=0;i<len;i++) scanf("%d",A+i);
        for(int i=0;i<len;i++) scanf("%d",B+i);
        for(int i=0;i<len;i++) a[i]=A[i],b[i]=B[i];
        orfwt(a,1),orfwt(b,1);
        for(int i=0;i<len;i++) a[i]=mul(a[i],b[i]);
        orfwt(a,0);
        for(int i=0;i<len;i++) printf("%d ",a[i]);
        puts("");
    
        for(int i=0;i<len;i++) a[i]=A[i],b[i]=B[i];
        andfwt(a,1),andfwt(b,1);
        for(int i=0;i<len;i++) a[i]=mul(a[i],b[i]);
        andfwt(a,0);
        for(int i=0;i<len;i++) printf("%d ",a[i]);
        puts("");
    
        for(int i=0;i<len;i++) a[i]=A[i],b[i]=B[i];
        xorfwt(a,1),xorfwt(b,1);
        for(int i=0;i<len;i++) a[i]=mul(a[i],b[i]);
        xorfwt(a,0);
        for(int i=0;i<len;i++) printf("%d ",a[i]);
        puts("");
        return 0;
    }
    

    2018.12.18

  • 相关阅读:
    gridview把textbox的值修改还是旧值的解决方法
    [转载]FMS Dev Guide学习笔记(验证客户端二)
    推荐几个Adobe Flex Builder 3的插件(代码格式化和fms服务器通讯文件(main.asc)编写)
    淘宝装修新旺铺如何让店招导航栏透明?
    淘宝店面怎么装修(不花分毫,玩转淘宝)
    教你处理明暗不匀的宝贝照片
    淘宝店铺装修 免费扶植版教程
    淘宝店铺(宝贝描述模板)克隆攻略
    如何用淘宝助理上传宝贝装修模板
    淘宝商城推广方案书
  • 原文地址:https://www.cnblogs.com/butterflydew/p/10136407.html
Copyright © 2020-2023  润新知