• 浅谈算法——FWT(快速沃尔什变换)


    其实FWT我啥都不会,反正就是记一波结论,记住就好……

    具体证明的话,推荐博客:FWT快速沃尔什变换学习笔记


    现有一些卷积,形如

    (C_k=sumlimits_{ilor j=k}A_i*B_j)

    (C_k=sumlimits_{iland j=k}A_i*B_j)

    (C_k=sumlimits_{ioplus j=k}A_i*B_j)

    然后普通的FFT肯定应付不了这玩意,于是就有了FWT(快速沃尔什变换),然后我就直接写结论好了……


    FWT——Or卷积

    我们把多项式(A)((2^n)项)拆成两部分(A_0,A_1),则有

    [FWT(A)=egin{cases}(FWT(A_0),FWT(A_0+A_1))&,n>0\A&,n=0end{cases} ]

    然后上面的部分是指两部分合到一块儿

    然后再给个性质

    [FWT(A)_i=sumlimits_{jlor i=i}A_j ]

    所以说统计子集和啥的就直接FWT一下就好了,还有个叫FMT(快速莫比乌斯变换)的,其实就是这玩意


    FWT——And卷积

    同样将多项式(A)拆开,有

    [FWT(A)=egin{cases}(FWT(A_0+A_1),FWT(A_1))&,n>0\A&,n=0end{cases} ]

    其实你发现和Or卷积差不多,咋记呢?你看(A_0,A_1)的差别就在最高位,然后Or((lor))肯定是答案贡献到1上去了,所以是后面加,然后And((land))就反过来,然后就这么记吧……

    同样的,这个卷积也有个性质

    [FWT(A)_i=sumlimits_{jland i=i}A_j ]

    这就相当于统计超集和了……


    FWT——Xor卷积

    这个东西还是要记一下的……

    [FWT(A)=egin{cases}(FWT(A_0)+FWT(A_1),FWT(A_0)-FWT(A_1))&,n>0\A&,n=0end{cases} ]

    然后这个貌似没有那啥奇怪性质……


    FWT讲完了,但是你不变换回来没啥用的啊……所以显然也要有IFWT

    然后IFWT也比较简单

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

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

    [oplus :IFWT(A)=(dfrac{IFWT(A_0)+IFWT(A_1)}{2},dfrac{IFWT(A_0)-IFWT(A_1)}{2}) ]


    然后贴个板子好了……

    void div(int &x){x=1ll*x*inv%p;}
    void FWT_xor(int *a,int n,int type){
    	for (int i=2;i<=n;i<<=1){
    		for (int j=0;j<n;j+=i){
    			for (int k=0;k<i>>1;k++){
    				int x=a[j+k],y=a[j+k+(i>>1)];
    				a[j+k]=(x+y)%p,a[j+k+(i>>1)]=(x-y+p)%p;
    				if (!~type)	div(a[j+k]),div(a[j+k+(i>>1)]);
    			}
    		}
    	}
    }
    void FWT_and(int *a,int n,int type){
    	for (int i=2;i<=n;i<<=1){
    		for (int j=0;j<n;j+=i){
    			for (int k=0;k<i>>1;k++){
    				(a[j+k]+=type*a[j+k+(i>>1)])%=p;
    				if (a[j+k]<0)	a[j+k]+=p;
    			}
    		}
    	}
    }
    void FWT_or(int *a,int n,int type){
    	for (int i=2;i<=n;i<<=1){
    		for (int j=0;j<n;j+=i){
    			for (int k=0;k<i>>1;k++){
    				(a[j+k+(i>>1)]+=type*a[j+k])%=p;
    				if (a[j+k+(i>>1)]<0)	a[j+k+(i>>1)]+=p;
    			}
    		}
    	}
    }
    
  • 相关阅读:
    c++中重载、重写、覆盖的区别
    c++值传递,指针传递,引用传递以及指针与引用的区别
    c/c++中static与extern关键字介绍
    Typedef和#define之间的区别
    c++中sizeof()的用法介绍
    c++笔试题:不使用第三个变量来交换俩个变量的数值
    c++位运算符介绍
    3.高并发教程-基础篇-之分布式全文搜索引擎elasticsearch的搭建
    2.高并发教程-基础篇-之nginx+mysql实现负载均衡和读写分离
    1.高并发教程-基础篇-之nginx负载均衡的搭建
  • 原文地址:https://www.cnblogs.com/Wolfycz/p/10435080.html
Copyright © 2020-2023  润新知