尝试自己理解一下原理。
首先是 FFT,解决的问题是将多项式和点值表达式在 O(nlogn) 时间内互相转化。
设要转化的多项式为 F(x),次数为 n,那么我们知道代入 n+1 个点值可以唯一确定这个多项式。
此处选用的点值为单位根,记 ωn 为 n 次单位根,即将平面直角坐标系上的单位圆均分成 n 份,几何意义是逆时针旋转 2πnrad。
由此容易得到一些性质,ω2k2n=ωkn,ωk+n2n=−ωkn 等。
现在设多项式为 F(x)=a0+a1x1+a2x2+⋯+an−1xn−1,要求的是 F(ω0n),F(ω1n),⋯,F(ωn−1n) 的值。
考虑分离奇偶项,设 F0(x)=a0+a2x+a4x2+⋯,F1(x)=a1+a3x+a5x2+⋯。
那么有 F(x)=F0(x2)+xF1(x2),尝试代入 ωkn。
分类讨论一下,若 k<n2,则有:
F(ωkn)=F0(ω2kn)+ωknF1(ω2kn)=F0(ωkn2)+ωknF1(ωkn2)
容易发现变成了两个规模减半的子问题。
若 k≥n2,则设 k′=k−n2,有:
F(ωkn)=F0(ωkn2)+ωk′+n2nF1(ωkn2)=F0(ωk′n2)−ωk′nF1(ωk′n2)
形式相同。
优化运算可以使用位运算置换,每次是将最低位奇偶分类,可以看作是二进制位逆序后的基数排序,所以一个数字的二进制位的逆序就是最终的位置,免去了递归计算的大常数。
根据定义式:F(ωxn)=n−1∑i=0aiωxin 可得这是一个线性变换,等价于乘范德蒙德矩阵。
由于这个矩阵的元素非常特殊,它的逆矩阵也有特殊的性质,就是每一项取倒数,再除以变换的长度 n,就能得到它的逆矩阵。
NTT 即将 ωn 用 gp−1n 代替,g 是模数 p 的原根,只因它们有相似的性质。
FWT 部分。
仿照 FFT 直接设计线性运算,设 c(i,j) 表示原多项式的第 j 项对 FWT 后多项式的第 i 项的贡献系数。
联立 FWT(A)i×FWT(B)i=FWT(A×B)i 和 FWT(A)i=n∑j=0c(i,j)Aj 可得 c(i,j)c(i,k)=c(i,j⊕k) 是等价条件,其中 ⊕ 是任意位运算,而位运算的一大优点在于其每位独立,故 c(i,j) 相当于 i,j 每一位的变换系数相乘。
计算 FWT(A)i=n−1∑j=0c(i,j)Aj 仍然考虑分治,记 i′ 表示 i 去掉最高位后的值,i0 表示 i 的最高位,j 同理。
FWT(A)i=n−1∑j=0c(i,j)Aj=n2−1∑j=0c(i,j)Aj+n−1∑j=n2c(i,j)Aj=c(i0,0)n2−1∑j=0c(i′,j′)Aj+c(i0,1)n−1∑j=n2c(i′,j′)Aj
转化为两个规模减半的子问题,根据 i0 的值计算即可。
推演 c([0,1],[0,1]) 的方法:
以 and 卷积为例。
首先有 c(i,0)c(i,j)=c(i,0),故有 c(i,0)=0 或 c(i,j)=1。
由于这是一个线性运算,矩阵必须满秩,所以不能存在一行或一列均为 0。
由此得到合法的矩阵可能是 [0111] 或者 [1101],逆运算直接乘上矩阵的逆即可。
解决的问题是计算 Fi=∑jandk=0∧jork=iajbk。
或卷积解决不了与为 0 的条件,考虑将其转化为 |j|+|k|=|i|,那么只需要在 F 内部维护一个多项式即可。
时间复杂度 O(n22n)。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】