卷积全家桶
你可能会问为什么这里只有 FWT,因为 FFT 和 NTT 我懒得写,好了,FFT 和 NTT 在写,2~3 天后补上。
快速沃尔什变换(FWT)
变换内容
快速沃尔什变换(下称 FWT)通常用来解决的问题形如
其中,
显然,对于数组(向量)
这样,我们可以通过求出
那么,如何构造
上述构造意在通过
进一步地,有
由
与
好的,现在我们发现了
下面,我们开始求
分开考虑它们下标(就是
这里,对于
其实,两个
下面我们将对
否则,有
尝试去掉
和
这里的加号表示数组对位相加,乘号表示数组中所有数都乘上一个数,下同。
综合以上,我们成功地将
等等!还没完!我们还只是通过
记
和
这两个性质都可以用
仔细观察
我们先记录下它左边的式子,有
记
记
回到
即
那么有
和
先只考虑
即
同理,对于
这样,我们只用拼接
观察 FWT 的
下面,让我们来讨论几组常见的卷积。记
一些常见卷积
按位或
此时
显然,它满足
那么有
和
即
这里所有的定义和前面一样,其中
现在我们需要做逆 FWT 变换,有
那么有
和
即
按位与
有构造
按位异或
有构造
在这里,你需要使用乘法逆元来计算
具体实现
参考代码:
void g_or(int *f, int tp) {
for (int x = 2; x <= n; x <<= 1) {
int k = x >> 1;
for (int i = 0; i < n; i += x) {
for (int j = 0; j < k; j++) {
f[i + j + k] = (f[i + j + k] + f[i + j] * tp + P) % P;
}
}
}
}
void g_and(int *f, int tp) {
for (int x = 2; x <= n; x <<= 1) {
int k = x >> 1;
for (int i = 0; i < n; i += x) {
for (int j = 0; j < k; j++) {
f[i + j] = (f[i + j] + f[i + j + k] * tp + P) % P;
}
}
}
}
void g_xor(int *f, int tp) {
for (int x = 2; x <= n; x <<= 1) {
int k = x >> 1;
for (int i = 0; i < n; i += x) {
for (int j = 0; j < k; j++) {
f[i + j] = (f[i + j] + f[i + j + k]) % P;
f[i + j + k] = (f[i + j] - (2 * f[i + j + k] % P) + P) % P;
f[i + j] = f[i + j] * tp % P;
f[i + j + k] = f[i + j + k] * tp % P;
}
}
}
}
未完待续...
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!