卷积
概念
令
形如
注意到多项式的乘法就是加法卷积
化成卷积形式的小技巧
减法卷积,下面默认
的长度都是 ,其中证明:
FFT
简介
可以将
与多项式有关的几个概念和约定
多项式的系数表示法:
多项式的点值表示法:
单位根
在复平面中,
模长:复数
幅角:假设以逆时针为正方向,从
在代数中
至于
然后我们能够发现关于单位根的三个显然的性质
,此处
FFT的原理
能够发现用过系数表示的两个
而用点值表示的两个
那么我们考虑是否存在低于
我们考虑将
不妨假设
能否发现我们将
现在还剩一个问题,我们还需要将点值表达转换为系数表达
考虑这样一个矩阵
我们现在知道
那么我们只需要乘前面那个矩阵的逆矩阵就能得到
首先前面那个矩阵的第
通过一些不为人知的方法 我们得到逆矩阵是
我们来验证一下,
我们知道
所以现在我们的系数变成
FFT的实现
递归
1 | void FFT(int n, Complex *a, int type) { |
注意到递归版本的常数太大,我们考虑使用非递归的版本
大概就是直接将所有系数换到递归底层的位置,然后合并即可
1 | struct Complex { |
精度比较好的写法,开long double可以跑1e15
1 | typedef std::vector<int> Poly; |
NTT
所以我们考虑取模意义下的一种新的单位根
经过前人的努力,我们得知这种数是原根
实际上
常用的模数是
还有
1 | #include <iostream> |
比较快的
1 | typedef std::vector<int> Poly; |
不知道为什么有奇怪错误的
1 | typedef std::vector<int> Poly; |
不知道为什么偶尔会出错的
1 | typedef std::vector<int> Poly; |
三模NTT
注意精度在
1 | int p; |
MTT
四次
1 | #define Poly vector<int> |
模x^2乘法NTT
单位元
1 | struct Int { |
集合运算卷积
FWT
大概就是求这个东西
首先我们考虑
在
实际上这个变换就是求一个高维前缀和,但是我们也可以参照
1 | typedef std::vector<int> Poly; |
子集卷积
大概就是求
我们考虑一般的或卷积,注意到第二个限制相当于
时间复杂度
1 | typedef std::vector<int> Poly; |
分治FFT以及分治FWT
分治
1 | void solve(Poly &A, const Poly &B, int l, int r) { // 区间左闭右开 |
分治
1 | void solve(int l, int r) { // 区间是左闭右开的形式,另外这个算的是先计算右半部分的 |
例题
简要题意:对于
的每个长度为 的子串求是否和 完美匹配, 和 均含有通配符,简要题解:构造函数
利用这个函数直接将
和翻转后的 卷起来简要题意:对于
的每个长度为 的子串中,有多少子串满足与 串 匹配, 匹配定义为有至多 个位置不同简要题解:构造函数
对于
的每一种字符单独求失配个数简要题意:现在有
个人,第 个人手里有一个数字 ,现在开始传数字,第 个人会将他手里的数字传给 , 是一个排列,同时现在有 次询问,每次询问给出一个整数 ,求传了 轮后,每个人的编号乘上他手里的数字的和简要题解:注意到传球形成了若干个简单环,我们对每个简单环单独计算贡献
我们设当前环的大小为
,第 个人的编号为 ,如果传了 轮,那么总贡献是类似于 的东西,稍作考虑后可以发现这是一个类似减法卷积的东西,将长度扩大到 ,然后再稍作处理直接做减法卷积即可,注意到总贡献刚好是 级别的,所以我们是可以用 的然后考虑处理询问,注意到大小不同的环的个数只有
,所以每次询问暴力所有环的大小即可时间复杂度
简要题意:给定两个长度均为
的序列 ,定义一个数对 的价值为 ,现在每个 和 都只能使用一次,求对于 ,选出 个数对的最大价值和以及最小价值和我们只需要考虑最大价值和,求最小价值和只需要将其中一个序列全部取反用同样的方法做即可
我们首先考虑如果没有负数,那么最大价值和一定是将
和 排序后对应位置匹配,如果有负数的话,能够发现,我们一定先凑价值为正的数对,即正正匹配,负负匹配,注意到这里的匹配也是按照绝对值的大小对应位置匹配我们现在考虑剩下的那一段,可以发现,一定是一个序列全负,一个序列全正,我们按照绝对值递增来排序,可以发现我们如果我们需要在这里选
对,那么匹配一定是 ,很显然这是一个卷积的形式,观察一下权值范围为 ,可以直接使用 ,时间复杂度2021-2022 ACM-ICPC Latin American Regional Programming Contest B Because, Art!
简要题意:数轴上有
个点,分别为 ,你现在在 ,从 走到 需要花费 的时间,有 的成功概率, 的概率走到 ,求走到 的期望时间简要题解:令
为从 走到 的概率,容易得到转移为注意到后面的
很像是一个分治 的形式,但是注意到我们的转移成环,但是对于这个形式,我们可以简单移项解决,我们可以得到 ,同时我们已知 ,要求 ,那么我们可以设 ,注意到 和 之间没有联系,可以直接拆成两个式子,这两个式子都是分治 的形式,直接做即可,时间复杂度简要题意:给定一个长度为
的序列 ,求 ,注意只对乘积取模,简要题解:我们注意到如果不是只对成绩取模,那么显然可以直接
,那么现在这种情况我们只能通过枚举值为 和值为 的乘积取模在乘上方案来计算答案注意到
是素数存在原根,那么我们转为枚举 和 ,我们知道 这个东西符合卷积的形式,使用 即可,时间复杂度