FWT学习笔记


引入

一般的多项式乘法是这样子的:

\(c_i=\sum_{i,j}a_j*b_k*[j+k==i]\)

但是如果我们将这个乘法式子里面的+号变换一下变成其他的运算符号呢?

\(c_i=\sum_{i,j}a_j*b_k*[j\oplus k==i]\)

其中\(\oplus\)可以取\(and,or,xor\)

这个时候FFT和NTT就没有什么用了...

前人的智慧是无穷的!

考虑一个神奇的算法:FWT(快速沃尔什变化)

or卷积

先从最容易的or卷积下手.

我们考虑他给出的式子:

\(c_i=\sum_{i,j}a_j*b_k*[i|j==k]\)

我们将i,j按照二进制拆开,发现这其实相当于是一个状压dp?

然后就可以直接搞了(因为这个二进制有传递的效果.)

上面是废话...

考虑怎么求这个玩意:

用一个式子:

\(FWT(A)=\begin{cases}(FWT(A_0),FWT(A_0+A_1)) & n\gt0 \\ A & n=0\end{cases}​\)

这个证明不会(真的菜)

然后只要把这个套进去就可以了(或还是比较简单)

然后就好了啊.qwq

and卷积

这个东西的话其实和or没有什么比较大的区别:

\(FWT(A)=\begin{cases}(FWT(A_0+A_1),FWT(A_1)) & n\gt0 \\ A & n=0\end{cases}\)

xor卷积

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

证明的坑以后会补的.

IFWT

考虑FFT我们怎么做的?

肯定是先把\(FFT(C)=FFT(A)*FFT(B)\)(这个是逐位乘)

然后再还原对吧.

所以FWT也需要还原.

然后既然怎么来的推出来了,怎么回去也就会了不是吗?

代码实现

namespace cpp1{
    int A[N],B[N],limit;
    void init(){
        limit=len;
        for(int i=0;i<limit;i++)A[i]=a[i];
        for(int i=0;i<limit;i++)B[i]=b[i];
    }
    void FMT(int *A,int limit,int opt){
        for(int i=1;i<limit;i<<=1)
            for(int j=0;j<limit;j++)
                if(i&j)
                    if(opt==1)A[j]=(A[j]+A[j^i])%Mod;
                    else A[j]=(A[j]+Mod-A[j^i])%Mod;
    }
    void solve(){
        FMT(A,limit,1);FMT(B,limit,1);
        for(int i=0;i<limit;i++)A[i]=(1ll*A[i]*B[i])%Mod;
        FMT(A,limit,-1);
        for(int i=0;i<limit;i++)printf("%d%c",A[i],i==limit-1?'\n':' ');
    }
}
namespace cpp2{
    int A[N],B[N],limit;
    void init(){
        limit=len;
        for(int i=0;i<limit;i++)A[i]=a[i];
        for(int i=0;i<limit;i++)B[i]=b[i];
    }
    void FWTand(int *a,int limit,int opt){
        for(int i=1;i<limit;i<<=1)
            for(int j=0,p=i<<1;j<limit;j+=p)
                for(int k=0;k<i;k++)
                    if(opt==1)a[j+k]=(a[j+k]+a[i+j+k])%Mod;
                    else a[j+k]=(a[j+k]-a[i+j+k]+Mod)%Mod;
    }
    void solve(){
        FWTand(A,limit,1);FWTand(B,limit,1);
        for(int i=0;i<limit;i++)A[i]=(1ll*A[i]*B[i])%Mod;
        FWTand(A,limit,-1);
        for(int i=0;i<limit;i++)printf("%d%c",A[i],i==limit-1?'\n':' ');
    }
}
namespace cpp3{
    int A[N],B[N],limit,inv2=499122177;
    void init(){
        limit=len;
        for(int i=0;i<limit;i++)A[i]=a[i];
        for(int i=0;i<limit;i++)B[i]=b[i];
    }
    void FWTxor(int *a,int limit,int opt){
        for(int i=1;i<limit;i<<=1)
            for(int p=i<<1,j=0;j<limit;j+=p)
                for(int k=0;k<i;k++){
                    int X=a[j+k],Y=a[i+j+k];
                    a[j+k]=(X+Y)%Mod;a[i+j+k]=(X+Mod-Y)%Mod;
                    if(opt==-1){
                        a[j+k]=1ll*a[j+k]*inv2%Mod;
                        a[i+j+k]=1ll*a[i+j+k]*inv2%Mod;
                    }
                }
    }
    void solve(){
        FWTxor(A,limit,1);FWTxor(B,limit,1);
        for(int i=0;i<limit;i++)A[i]=(1ll*A[i]*B[i])%Mod;
        FWTxor(A,limit,-1);
        for(int i=0;i<limit;i++)printf("%d%c",A[i],i==limit-1?'\n':' ');
    }
}

FWT学习笔记的更多相关文章

  1. 一个数学不好的菜鸡的快速沃尔什变换(FWT)学习笔记

    一个数学不好的菜鸡的快速沃尔什变换(FWT)学习笔记 曾经某个下午我以为我会了FWT,结果现在一丁点也想不起来了--看来"学"完新东西不经常做题不写博客,就白学了 = = 我没啥智 ...

  2. FWT 学习笔记

    FWT学习笔记 好久以前写的,先粘上来 定义数组 \(n=2^k\) \(A=[a_0,a_1,a_2,a_3,...,a_{n-1}]\) 令\(A_0=[a_0,a_1,a_2,...,a_{\f ...

  3. FMT/FWT学习笔记

    目录 FMT/FWT学习笔记 FMT 快速莫比乌斯变换 OR卷积 AND卷积 快速沃尔什变换(FWT/XOR卷积) FMT/FWT学习笔记 FMT/FWT是算法竞赛中求or/and/xor卷积的算法, ...

  4. $\text {FWT}$学习笔记

    \(\text {FWT}\) 学习笔记 正常项的\(\text {FWT}\) 在\(\text {OI}\)中,我们经常会碰到这种问题: 给出一个长度为\(n\)的序列\(a_{1,2,...,n ...

  5. 快速沃尔什变换 (FWT)学习笔记

    证明均来自xht37 的洛谷博客 作用 在 \(OI\) 中,\(FWT\) 是用于解决对下标进行位运算卷积问题的方法. \(c_{i}=\sum_{i=j \oplus k} a_{j} b_{k} ...

  6. 快速沃尔什变换 FWT 学习笔记【多项式】

    〇.前言 之前看到异或就担心是 FWT,然后才开始想别的. 这次学了 FWT 以后,以后判断应该就很快了吧? 参考资料 FWT 详解 知识点 by neither_nor 集训队论文 2015 集合幂 ...

  7. 快速沃尔什变换(FWT)学习笔记 + 洛谷P4717 [模板]

    FWT求解的是一类问题:\( a[i] = \sum\limits_{j\bigoplus k=i}^{} b[j]*c[k] \) 其中,\( \bigoplus \) 可以是 or,and,xor ...

  8. 卷积理论 & 高维FWT学习笔记

    之前做了那么多生成函数和多项式卷积的题目,结果今天才理解了优化卷积算法的实质. 首先我们以二进制FWT or作为最简单的例子入手. 我们发现正的FWT or变换就是求$\hat{a}_j=\sum_{ ...

  9. FWT快速沃尔什变换学习笔记

    FWT快速沃尔什变换学习笔记 1.FWT用来干啥啊 回忆一下多项式的卷积\(C_k=\sum_{i+j=k}A_i*B_j\) 我们可以用\(FFT\)来做. 甚至在一些特殊情况下,我们\(C_k=\ ...

随机推荐

  1. 重新设置Linux的IP地址(该操作会永久更改ip地址)

    1.查看你当前的IP地址 2.进入配置文件进行更改IP地址 3.上图我使用的是ifcfg-eth1 ,然后进行更改这个文件 4.点击“insert”进行编辑改文档,吧对应的IP改成你想要的地址 更改完 ...

  2. mybatis学习 十六 auto_mapping实现连表查询

    只能使用多表联合查询方式. 要求:查询出的列别和属性名相同. 点字符  "."  在 SQL 是关键字符,两侧添加反单引号(Tab键上的一个字符) <select id=&q ...

  3. 日志审计系统、事件日志审计、syslog审计

    日志审计系统.事件日志审计.syslog审计 任何IT机构中的Windows机器每天都会生成巨量日志数据.这些日志包含可帮助您的有用信息: · 获取位于各个Windows事件日志严重性级别的所有网络活 ...

  4. python学习 day16 (3月21日)----(正则)

    背景:(对程序的伤害) #__author : 'liuyang' #date : 2019/3/21 0021 上午 10:34 #模块和功能之间的关系 #先有的功能 #正则表达式 #time模块 ...

  5. 核心一:IoC

    IoC 1.中文名称:控制反转 2.英文名称:(Inversion of Control) 3.IoC是什么? 3.1 IoC 完成的事情原先由程序员主动通过new 实例化对象事情,转交给Spring ...

  6. 720. Longest Word in Dictionary

    static int wing=[]() { std::ios::sync_with_stdio(false); cin.tie(NULL); ; }(); class Solution { publ ...

  7. 2018.10.29 bzoj1023: [SHOI2008]cactus仙人掌图(仙人掌+单调队列优化dp)

    传送门 求仙人掌的直径. 感觉不是很难. 分点在环上面和不在环上分类讨论. 不在环上直接树形dpdpdp. 然后如果在环上讨论一波. 首先对环的祖先有贡献的只有环上dfsdfsdfs序最小的点. 对答 ...

  8. openstack之flavor管理

    概览 [root@cc07 ~]# nova help | grep flavor flavor-access-add Add flavor access for the given tenant. ...

  9. mysql 查询中文字段 没有结果的解决方法

    代码如下: $conn = new mysqli('localhost', 'root', '', 'excel');$sql = "select 中信一级行业 from excel gro ...

  10. s5-15 开放的最短路径优先_OSPF

    L-S路由协议的实例—OSPF 开放的路径优先(Open Shortest Path First) 使用图(graph)来表述真实的网络 - 每个路由器/Lan都是一个节点 - 测量代价/量度(met ...