快速沃尔什变换与k进制FWT
这是一篇用来卖萌的文章QAQ
考虑以下三类卷积
Ck=∑iorj=kAi∗BjCk=∑iorj=kAi∗Bj
Ck=∑iandj=kAi∗BjCk=∑iandj=kAi∗Bj
Ck=∑ixorj=kAi∗BjCk=∑ixorj=kAi∗Bj
由于前两种可以用FMT(高维前缀和)解决,那我们就谈谈第三种吧
下文中的nn都是形如2i−12i−1的数
下标的开与闭是根据好不好写来定的,但是还是可以意会的...
虽然有人知道为什么了,但是我还是不知道为什么要这么做
我们尝试寻找一个矩阵TT,其(i,j)(i,j)元为w(i,j)w(i,j),使得
我们不妨记TA=fwt(A)TA=fwt(A)
自然的,fwt(A)[x]=n∑i=0w(x,i)∗Aifwt(A)[x]=n∑i=0w(x,i)∗Ai
那么,等式两边同时展开,我们可以得到
对比两边CkCk的表达式, 我们自然希望这个变换满足
如果有w(x,i)∗w(x,j)=w(x,k)(i⊕j=k)w(x,i)∗w(x,j)=w(x,k)(i⊕j=k),那么我们就能得到∑i⊕j=kAi∗Bj=Ck∑i⊕j=kAi∗Bj=Ck
这不就是我们想要的式子嘛....,
那我就构造一个满足w(x,i)∗w(x,j)=w(x,k)(i⊕j=k)w(x,i)∗w(x,j)=w(x,k)(i⊕j=k)的TT矩阵
不仅如此,我们还需要可以快速地计算出fwt(A)fwt(A)
不难注意到,前半部分已经成为了一个子问题,然而后半部分还没有
我们希望通过w的某些性质,能够使得右边成为一个子问题
联想到w需要满足异或的性质,因此,我们不妨让w拥有可以按位拆分的性质
下面的化式子来源于rqy神仙
如果有上面的性质,我们记i的二进制的最高位为i1,其他位为i0,k同理
那么,原本的式子可以转化成
应该看得出A0和A1是什么吧...
复杂度为T(n)=2T(n/2)+O(n)=O(nlogn)
那么,考虑构造w,其实只要构造一个2∗2的矩阵,由于C需要逆变换,因此矩阵还要有逆
根据上面的异或性质,我们有
注意到矩阵要有逆,因此秩需要为2
然后就可以弄出这么一个矩阵
然后代进程序即可
k进制FWT
计算Ck=∑i⊕j=kAi∗Bj
由于K进制下,FMT仍然能解决或卷积以及和卷积,因此FWT一般用来解决异或卷积
在下文中,n=Ki−1
自然地,还是希望构造TA⋅TB=TC
还是一样的展开
还是一样的对比系数,然后我们能够得出,当w(x,i)∗w(x,j)=w(x,k)(i⊕j=k)时,这样子做的正确性有保证
并且,同样的,不妨设i=(i0i1i2...im)k
那么,我们构造w(i,j)=m∏t=0w(it,jt)
我们根据i在k进制下的最高位来讨论,我们记一个数x在k进制下的最高位为x′,其余位为x″
复杂度是T(n)=kT(n/K)+O(Kn)=O(nKlogKn)(n是K的幂)
我们需要考虑K∗K的T矩阵是什么
由于w(x,i)∗w(x,j)=w(x,k)(i⊕j=k),也就是w(x,i)∗w(x,j)=w(x,k)([K|i+j−k])
注意到单位根在复平面意义下有循环的意义
因此,我们尝试取w(x,i)=wxik,那么我们取出来的实际上就是范德蒙德矩阵!
由于范德蒙德卷积的行列式为∏i<j(xi−xj),在这个单位根矩阵中,不存在两两相等的数
因此这个有逆,事实上, 在FFT中,我们早已经见过这个矩阵的逆矩阵了,它是
原因是[n|t]=n−1∑i=0wtin
这样,我们就可以成功的计算出k进制FWT啦!
感谢rqy和dkw的提示
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
· 上周热点回顾(2.17-2.23)