文章目录

  • 前言
  • 一、例题
  • 二、思路与代码
    • 1.思路
    • 2.代码

前言

在学过FFT/NTT后,我们已经可以解决许多多项式问题了,而出题人觉得还不够

所以我们接着来处理更复杂的多项式卷积------快速沃尔什变换和快速莫比乌斯变换

很多时候,人们把这两个变换同称为一个快速沃尔什变换,但实际上它们是分开的

快速莫比乌斯变换是来解决 与卷积、或卷积(也可认为是交卷积、并卷积)

note: 下文中我们的 ∗*∗ 不是卷积符号,仅仅是乘法

我们重新来看多项式的运算的定义:
C=A+B,C[k]=∑i=j=kA[i]+B[j]C = A + B,C[k]=\sum_{i=j=k}A[i]+B[j]C=A+B,C[k]=i=j=k∑​A[i]+B[j] C=A×B,C[k]=∑i+j=kA[i]B[j]C = A \times B,C[k]=\sum_{i+j=k}A[i]B[j]C=A×B,C[k]=i+j=k∑​A[i]B[j] C=A∣B,C[k]=∑i∣j=kA[i]B[j]C = A \mid B,C[k]=\sum_{i|j=k}A[i]B[j]C=A∣B,C[k]=i∣j=k∑​A[i]B[j] C=A&B,C[k]=∑i&j=kA[i]B[j]C = A \And B,C[k]=\sum_{i \And j=k}A[i]B[j]C=A&B,C[k]=i&j=k∑​A[i]B[j] C=A⊗B,C[k]=∑i⊗j=kA[i]B[j]C = A \otimes B,C[k]=\sum_{i \otimes j=k}A[i]B[j]C=A⊗B,C[k]=i⊗j=k∑​A[i]B[j]
此时,我们也看的出来,多项式的算术运算和位运算还是有蛮大的区别
加法运算可线性得出,乘法运算则利用FFT/NTT亚线性得出
算数运算和位运算则是两条思路,一个寻找去寻找单位元,一个去寻找反演不变性

在位运算中,与运算、或运算属于FMT的范畴
因为本质上它们来源于集合上的莫比乌斯反演,与对应交,或对应并
而出题人最长出的异或则来源于快速沃尔什变换,其实也可以对应集合差的和

当然,这两个变换自然地借鉴了FFT/NTT的思想,即寻找一种变换和新运算使得多项式可以快速运算

FMT中,我们以或运算为例,寻求一种变换FMT(S)FMT(S)FMT(S)和新运算U⋅VU \cdot VU⋅V,使得FMT(C)=FMT(A∣B)=FMT(A)⋅FMT(B)FMT(C)=FMT(A|B)=FMT(A)\cdot FMT(B)FMT(C)=FMT(A∣B)=FMT(A)⋅FMT(B)自然地,U⋅VU\cdot VU⋅V这个运算就让它是对应项相乘这个O(n)O(n)O(n)运算好了,现在的问题就找变换了,使得:FMT(∑k∑i∣j=kA[i]B[j])=FMT(∑kA[k])FMT(∑kB[k])FMT(\sum_k\sum_{i|j=k}A[i]B[j])=FMT(\sum_kA[k])FMT(\sum_kB[k])FMT(k∑​i∣j=k∑​A[i]B[j])=FMT(k∑​A[k])FMT(k∑​B[k])此时,我们想到了集合上的莫比乌斯反演相关性质,受此启发∑l⊂k∑i∪j=lA[i]B[j]=∑(i∪j)⊂kA[i]B[j]=∑i⊂kA[i]∑j⊂kB[j]\sum_{l\subset k}\sum_{i \cup j=l}A[i]B[j]=\sum_{(i\cup j)\sub k}A[i]B[j]=\sum_{i\sub k}A[i]\sum_{j\sub k}B[j]l⊂k∑​i∪j=l∑​A[i]B[j]=(i∪j)⊂k∑​A[i]B[j]=i⊂k∑​A[i]j⊂k∑​B[j]我们来定义FMTFMTFMT为子集和: FMT(A)[k]=∑i⊂kA[i]FMT(A)[k]=\sum_{i\sub k}A[i]FMT(A)[k]=i⊂k∑​A[i]或者说:FMT(A)[k]=∑i∣k=kA[i]FMT(A)[k]=\sum_{i|k=k}A[i]FMT(A)[k]=i∣k=k∑​A[i]这样我们就可以解决其变换后的快速运算了,那进行变换本身的时间复杂度如何呢,

我们找找它的性质,发现:FMT(<ϕ,U>)=<FMT(ϕ),FMT(ϕ+U)>FMT(<\phi,U>)=<FMT(\phi),FMT(\phi+U)>FMT(<ϕ,U>)=<FMT(ϕ),FMT(ϕ+U)> FMT(<A0,A1>)=<FMT(A0),FMT(A0+A1)>FMT(<A_0,A_1>)=<FMT(A_0),FMT(A_0+A_1)>FMT(<A0​,A1​>)=<FMT(A0​),FMT(A0​+A1​)>其中A0A_0A0​代表数位为0,A1A_1A1​代表数位为1,很好,可以递归下去

and运算也有相似的性质,此处的变换不再是子集和,而是超集和FMTor(<A0,A1>)=<FMTor(A0),FMTor(A0+A1)>FMTor(<A_0,A_1>)=<FMTor(A_0),FMTor(A_0+A_1)>FMTor(<A0​,A1​>)=<FMTor(A0​),FMTor(A0​+A1​)> FMTand(<A0,A1>)=<FMTand(A0+A1),FMTand(A1)>FMTand(<A_0,A_1>)=<FMTand(A_0+A_1),FMTand(A_1)>FMTand(<A0​,A1​>)=<FMTand(A0​+A1​),FMTand(A1​)>
然后,我们来到FWT,它要解决异或问题,此时它似乎不再有上述性质了,我们需要另寻思路,
这时,我们可以考虑广义的模2,这样只需奇偶位对应即可,实际上两个递推左右交换也是可以的FWTxor(<A0,A1>)=<FWTxor(A0+A1),FWTxor(A0−A1)>FWTxor(<A_0,A_1>)=<FWTxor(A_0+A_1),FWTxor(A_0-A_1)>FWTxor(<A0​,A1​>)=<FWTxor(A0​+A1​),FWTxor(A0​−A1​)>

一、例题

例题:洛谷 P4717

二、思路与代码

1.思路

很板子的一道板子题,直接上模板

2.代码

代码如下:

#include <iostream>
#define int long long
using namespace std;
const int mod = 998244353;
const int maxn = 1e7 + 9;
int n, N;
int a[maxn], b[maxn], ans[maxn];
int tempa[maxn], tempb[maxn];
int quickpow(int a, int n) {int ans = 1;while (n) {if (n & 1) ans = ans * a % mod;a = a * a % mod;n >>= 1;}return ans;
}
int inv2 = quickpow(2, mod - 2);
// int inv2 = (mod + 1) / 2;
void FMTor(int a[], int inv) {for (int i = 1; i < N; i <<= 1) {for (int j = 0, p = i << 1; j < N; j += p)for (int k = 0; k < i; k++)a[i + j + k] = (a[i + j + k] + inv * a[j + k] + mod) % mod;}
}
void FMTand(int a[], int inv) {for (int i = 1; i < N; i <<= 1)for (int j = 0, p = i << 1; j < N; j += p)for (int k = 0; k < i; k++)a[j + k] = (a[j + k] + inv * a[i + j + k] + mod) % mod;
}
void FWTxor(int a[], int inv) {for (int i = 1; i < N; i <<= 1)for (int j = 0, p = i << 1; j < N; 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 - y + mod) % mod;if (inv == -1) {a[j + k] *= inv2, a[i + j + k] *= inv2;a[j + k] %= mod, a[i + j + k] %= mod;}}
}
signed main() {//   freopen("in.txt", "r", stdin);//   freopen("out.txt", "w", stdout);scanf("%d", &n);N = 1 << n;for (int i = 0; i < N; i++) scanf("%d", &a[i]);for (int i = 0; i < N; i++) scanf("%d", &b[i]);for (int i = 0; i < N; i++) tempa[i] = a[i], tempb[i] = b[i];FMTor(tempa, 1), FMTor(tempb, 1);for (int i = 0; i < N; i++) ans[i] = tempa[i] * tempb[i] % mod;FMTor(ans, -1);for (int i = 0; i < N; i++) printf("%d ", ans[i]);printf("\n");for (int i = 0; i < N; i++) tempa[i] = a[i], tempb[i] = b[i];FMTand(tempa, 1), FMTand(tempb, 1);for (int i = 0; i < N; i++) ans[i] = tempa[i] * tempb[i] % mod;FMTand(ans, -1);for (int i = 0; i < N; i++) printf("%d ", ans[i]);printf("\n");for (int i = 0; i < N; i++) tempa[i] = a[i], tempb[i] = b[i];FWTxor(tempa, 1), FWTxor(tempb, 1);for (int i = 0; i < N; i++) ans[i] = tempa[i] * tempb[i] % mod;FWTxor(ans, -1);for (int i = 0; i < N; i++) printf("%d ", ans[i]);printf("\n");return 0;
}

FWT / FMT 快速沃尔什/莫比乌斯变换 P4717相关推荐

  1. 模板:快速莫比乌斯变换(FMT)+快速沃尔什变换(FWT)(多项式)

    文章目录 前言 解析 OR 定义 变换: 逆变换 代码 AND 代码 XOR 定义 变换 逆变换 代码 所谓快速沃尔什变换,就是快速的沃尔玛什锦专柜变换 (逃) 前言 正常卷积的定义:ck=∑i+j= ...

  2. 《小学生都能看懂的快速沃尔什变换从入门到升天教程》(FWT / FMT / FMI)(最最严谨清晰的证明!零基础也能得学会!)

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 目录 0x00 卷积 0x01 多项式 0x02 卷积的定义 0x03 卷积的基本性质 0x04 位运 ...

  3. 快速沃尔什变化(FWT)介绍

    快速沃尔什变化(FWT)介绍 能看到这篇博客的人,一定知道FWT是干什么的.(什么?你不知道?) 没事,这里有picks讲FWT的一篇博客.先点进去看一看. 如果你看懂了,那么恭喜你.如果你跟我一样看 ...

  4. NOI数学:莫比乌斯变换

    P5491 [模板]二次剩余 [模板]二次剩余 - 洛谷 P1082 [NOIP2012 提高组] 同余方程 [NOIP2012 提高组] 同余方程 - 洛谷 [模板题]Luogu-P4717 快速莫 ...

  5. 浅谈FFT(快速博立叶变换)学习笔记

    0XFF---FFT是啥? FFT是一种DFT的高效算法,称为快速傅立叶变换(fast Fourier transform),它根据离散傅氏变换的奇.偶.虚.实等 特性,对离散傅立叶变换的算法进行改进 ...

  6. matlab 沃尔什,Walsh-Hadamard 变换

    Walsh-Hadamard 变换 Walsh-Hadamard 变换是一种将信号分解成一组基函数的非正弦类正交变换方法.这些基函数是 Walsh 函数,它们是值为 +1 或 –1 的矩形波或方波.W ...

  7. 容斥原理与欧拉函数与莫比乌斯函数,狄利克雷卷积与莫比乌斯变换,反演

    莫比乌斯函数可以看成是一种被内化了的容斥原理,许多数论上的结论定理根据容斥原理和数学归纳法可以推导出来,但是有关容斥原理的表达式的构造往往并不容易,运气不好很难找到,而莫比乌斯函数则是巧妙的把容斥原理 ...

  8. FFT(快速博立叶变换)

    证明请参考算法概论的快速博立叶. FFT递归: #include <bits/stdc++.h> using namespace std; const int maxn = 5005; c ...

  9. [hdu4609]3-idiots(快速傅利叶变换FFT)

    题目名字是三个制杖- [题意] 有T组数据 每组数据给出n条线段,问任意取三条,可以组成三角形的概率 [输入] 开头一行输入T(T<=10) 下来T组数据,每组数据第一行输入一个n(3<= ...

最新文章

  1. C#方法参数传递-同时使用ref和out关键字
  2. 表贴电阻尺寸与什么有关_为什么电阻的长度与电阻的大小有关系
  3. w3c的html4.0规范,W3C HTML4.0学习
  4. Android基础教程(三)之------ Activity 窗口切换
  5. centos5安装oracle11,CentOS 6.5 x64 安装 Oracle11g R2
  6. 使用eclipse新建一个SWT工程
  7. [老老实实学WCF] 第五篇 再探通信--ClientBase
  8. Windows Server 2016-WinSer 2016标准版与数据中心版的区别
  9. Dreamweaver网页课设做家乡网站
  10. [软件更新]CuteFTP 8.3.3.0054
  11. 多测师_设置 Linux 支持中文
  12. 计算机技术学硕国家线,关于工科国家线专硕学硕
  13. js实现雪花飘落效果
  14. 如何学计算机作文3000到500,作文学习电脑500字(共8篇)
  15. android 后台实时定位,实现后台定位,持续无限制定位
  16. 关于奇异值分解的一些讨论
  17. 出现无法访问的故障,ping出现请求超时time out,系目的主机网关造成问题排查过程
  18. 深度学习 数码管_创新研发基于深度学习的可见光智能检测技术
  19. 亚马逊 广告接口对接 amazon advertising
  20. js生日计算年龄_「周岁怎么算」【js】根据出生日期,计算周岁年龄 - seo实验室...

热门文章

  1. 英语四级作文计算机,2019年6月英语四级作文范文:电脑
  2. Codeforces Round #797 (Div. 3)无F
  3. 手机拍摄实时互联网直播解决方案
  4. 小程序开发后,该如何推广?
  5. qq邮箱附件文件名乱码处理方法
  6. AD5290YRMZ10 adi亚德诺
  7. 给查询的SQL中自动增加 自增长 序号
  8. matlab 数值范围,matlab中怎么样表示自变量的取值范围
  9. 处理原始scRNA-Seq测序数据:从reads到计数矩阵
  10. 抓娃娃机按钮按几下_夹娃娃的技巧攻略 抓娃娃的容易中的招数