位运算卷积

我的 FWT 因为实现原因可能爆负数,但是加个取模是对的喵。

概念

位运算卷积(FWT)

加法卷积的 “加法” 意为第 i 项和第 j 项的结果贡献到第 i+j 项。

类似地,做位运算卷积时多项式的第 i 项和第 j 项贡献到第 ij 项,其中 是某一位运算。

  • 形式化定义:S[k]=ij=kA[i]B[j],记作 AB=S.

位矩阵

FFT 的作用是把多项式转化成点值表示之后,将卷积直接转化成点积。类似地,FWT 的作用也是将位运算卷积转化成直接点积。

FWT(A) 表示幂级数 A 经过 FWT 变换之后得到的幂级数。

FWT 和 FFT 都是线性变换,考虑设变换系数 c(i,j),表示 A[j]FWT(A)[i] 的贡献系数,也就是 FWT(A)[i]=j=0n1c(i,j)A[j].

将上式代入 FWT(A)FWT(B)=FWT(C),化简可得 j=0n1k=0n1c(i,j)c(i,k)A[j]B[k]=p=0n1c(i,p)C[p].

又因为 AB=C,可以得到 C[p]=t1t2=pA[t1]B[t2].

将上面二式代入分别代入 p=0n1c(i,p)C[p],可以得到 j=0k=0n1c(i,j)c(i,k)A[j]B[k]=p=0n1t1t2=pA[t1]B[t2]c(i,t1t2)=t1=0n1t2=0n1A[t1]B[t2]c(i,t1t2).

对比可得 c(i,j)c(i,k)=c(i,jk),只需要考虑构造出符合条件的 c 即可。

又因为位运算具有独立性,所以可以拆位考虑,只需要求出满足条件的 c[0,1],[0,1]

c 可以写作矩阵的形式,称为位矩阵。

一些常用的位矩阵:

  • 或卷积:[1011]

    逆矩阵:[1011]

  • 与卷积:[1101]

    逆矩阵:[1101]

  • 异或卷积:[1111]

    逆矩阵:[12121212]

FWT 变换

类似 FFT,考虑分类,按位拆半。

FWT(A)[i]=j=0n1c(i,j)A[j]=j=0n21c(i,j)A[j]+j=n2n1c(i,j)A[j].

ii 去掉二进制下首位剩下的数,i0i 二进制表示中最高位上的数(此处均钦定二进制表示的最高位)

根据位矩阵的定义可得原式等价于:

j=0n21c(i0,j0)c(i,j)A[j]+j=n2n1c(i0,j0)c(i,j)A[j].

根据按位拆半可得:

j=0n21c(i0,0)c(i,j)A[j]+j=n2n1c(i0,1)c(i,j)A[j].

注意到 c(i,j)c(i,j) 规模减半。

A0 为幂级数下标的二进制表示最高位为 0 的部分,A1 同理,则:

i0=0 时:

FWT(A)[i]=c(0,0)FWT(A0)[i]+c(0,1)FWT(A1)[i].

i0=1 时:

FWT(A)[i+n2]=c(1,0)FWT(A0)[i]+c(1,1)FWT(A1)[i].

于是根据上式,可以以 O(n) 的代价合并两个长度为 n2 的子变换。

n=2m 时,复杂度为 O(m2m)。看起来很大,但实际上是 O(nlogn) 级别的 /xk

逆变换 IFWT 就是对 c 求逆再进行变换。

做一次或卷积相当于求子集信息和,做一次与卷积相当于求超集信息和。

FWT 在一定程度上是可以代替 FMT 和高维前缀和的。

下面模板图一乐就行,正常不会这么写。

P4717 【模板】快速莫比乌斯/沃尔什变换 (FMT/FMT)

子集卷积

ck=i&j=0,ij=kaibj.

应该可以用来优化一类状压 dp.

|i| 表示 i 的二进制表示中 1 的个数。i&j=0,ij=k 等价于 ij=s,|i|+|j|=|s|.

考虑再开一维记录 |i|,对每一维分别卷积就行。

时间复杂度 O(m22m)

P6097 【模板】子集卷积

FWT 快速幂

在 FWT 意义下求 Ft(x).

考虑先进行一次 FWT,然后对于每个点值直接取其 t 次方,最后 IWFT 回来就行。

例题:[BZOJ4589] Hard Nim

posted @   kymru  阅读(99)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 上周热点回顾(2.17-2.23)
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 如何使用 Uni-app 实现视频聊天(源码,支持安卓、iOS)
点击右上角即可分享
微信分享提示
主题色彩