FFT与NTT专题
先不管旋转操作,考虑化简这个差异值
$$
begin{aligned}
sum_{i=1}^n(x_i-y_i-c)^2
&=sum_{i=1}^n(x_i-y_i)^2+nc^2-2csum_{i=1}^n(x_i-y_i)\
&=sum_{i=1}^nx_i^2+sum_{i=1}^ny_i^2+nc^2-2csum_{i=1}^n(x_i-y_i)-2sum_{i=1}^nx_iy_i
end{aligned}
$$
注意到$sum x^2+sum y^2$是常数,先不管
可以发现,这是一个关于$c$的二次函数
那么我们知道,此时$c$的极值点就在$-frac{b}{2a}$处
所以,我们可以得出$c$的最优值是
$$
frac{sum_{i=1}^n x_i-sum_{i=1}^n y_i}{n}
$$
而分子的两个数均与旋转无关
但是$c$只能是整数
所以判一下$c, c-1, c+1$哪个与上面的式子更接近
注意到旋转唯一能改变的是$sum xy$
而我们要让这个值尽量小
设
$$
F(m)=sum_{i=1}^nx_iy_{i+m}
$$
我们可以看出,这是一个类似卷积的东西
但是一般的卷积是后两式下标的和不变
而这个是差不变
所以把这个式子变一下
设
$$
x_{n-i+1}=x_i
$$
就是将x倒序一下
可以得到
$$
F(m)=sum_{i=1}^nx_{n-i+1}y_{i+m}
$$
不妨设后面$xy$的卷积是$A$,也就是
$$
A(n+m+1)=sum_{i=1}^nx_{n-i+1}y_{i+m}
$$
可以发现,这个$A$就是将$F$整体向右平移了$n+1$
所以
$$
F(m)=A(n+m+1)
$$
为了不丢精度,NTT即可(保证答案不会超过mod)
代码如下
1 |
using namespace std; |
B – 求和
我们知道
$$
S(n,m)=sum_{i=0}^m(-1)^i{mchoose i}(m-i)^nfrac{1}{m!}
$$
原理很简单,容斥有几个盒子没有放球,有$mchoose i$种选法,再将$n$个球放入$m-i$个盒子。由于盒子是无序的,最后除以$m$的阶乘
那么我们用这个化简原式
注意到第二个$sum$的上界是$i$,非常讨厌
由于斯特林数的性质,把这个$i$换成$n$也没有问题
因为当$m>n$时,$S(n,m)=0$
所以有
$$
begin{aligned}
sum_{i=0}^nsum_{j=0}^nS(i,j)*2^j*j!
&=sum_{j=0}^n2^j*j!sum_{i=0}^nsum_{k=0}^j(-1)^k{jchoose k}(j-k)^ifrac{1}{j!}\
&=sum_{j=0}^n2^j*j!sum_{k=0}^jfrac{(-1)^k}{k!}*frac{sum_{i=0}^n(j-k)^i}{(j-k)!}
end{aligned}
$$
注意到后面那个是卷积的形式
第一个多项式很好求,第二个的分子是等比数列
我们设$B$是第二个多项式
显然有
$$
B(0)=0, B(1)=n+1
$$
对于其它情况,直接用等比数列求和公式算出来就行了
代码如下
1 |
using namespace std; |
C – 序列统计
这题的难点在于转化成原根
注意到要求的是所有数的乘积而非和
如果是和的话直接NTT就好了
那么我们就将乘积转化成和的形式
如果两个数都是某个数的某次方,那么这两个数乘起来就是指数相加
而原根恰好可以表示模$m$剩余系下的每个数
所以把每个数转化成原根的某次方就好了
求原根代码
1 |
inline int G(int x) {
|
D – 残缺的字符串
带通配符的字符串匹配问题
首先考虑不带通配符的怎么做
那么拓展KMP, 后缀数组都可以
但是我们有一个更高级的方法:FFT求字符串匹配
首先我们需要定义“匹配”
所以设差异函数$g(i)$表示从$B$串的$i$位置开始,与$A$串的差异程度
有
$$
g(x)=sum_{i=x}^{x+m-1}(B_i-A_{i-x+1})^2
$$
显然,只有当$A$串从$x$位置开始与$B$串完全相同,$g$的值才为0
化简原式
$$
begin{aligned}
g(x)&=sum_{i=x}^{x+m-1}A_{i-x+1}^2+sum_{i=x}^{x+m-1}B_i^2-2sum_{i=x}^{x+m-1}B_iA_{i-x+1}\
&=sum_{i=1}^mA_i^2+sum_{i=1}^mB_{i+x-1}^2-2sum_{i=1}^mA_iB_{i+x-1}
end{aligned}
$$
前两项可以通过预处理前缀和得出,后面的是一个下标差相等的卷积
那么模仿之前的套路,我们将$A$序列倒序一下再求卷积就行了
解决了不带通配符的问题,再考虑带通配符
这个通配符是可以匹配任意字符的,所以把差异函数改一下
$$
g(x)=sum_{i=x}^{x+m-1}(B_i-A_{i-x+1})^2A_{i-x+1}B_i
$$
当$i$处的字符是$*$时,我们设那个地方的值为0
化简得
$$
=sum_{i=1}^mA_i^3B_{i-x+1}+sum_{i=1}^mA_iB_{i-x+1}^3-2sum_{i=1}^xA_i^2B_{i-x+1}^2
$$
做3次FFT即可
代码如下
1 |
using namespace std; |
E – 万径人踪灭
假设当前确定了一个对称中心$i$
那么当两个位置$j,k$关于i对称且这两个位置的字母相同时对答案有贡献
对称则意味着$j+k=i*2$,可以FFT
枚举字符,然后FFT
假设这个中心有x对这样的位置
那么每一对都是独立的,可以选也可以不选,但是不能都不选
所以此时的答案为$2^x-1$
题目要求不能全部连续,那么最后再跑一边manacher,减去全部连续的答案即可
代码如下
1 |
using 大专栏 FFT与NTT专题s="keyword">namespace std; |
F – 性能优化
这道题利用到了FFT的原理
如果模数是质数,那么非常好办
但是这题不仅模数不是质数,而且求的是循环卷积,直接FFT会爆炸
贴一篇我觉得很好的题解

这个rev数组可以模拟FFT的过程,递归地求出来
单位根满足消去律,上面的$F(omega_n^i)$指的是$ileq frac{n}{p}$的情况
对于剩余的情况,有$omega_{frac{n}{p}}^i=omega_{frac{n}{p}}^{i-frac{n}{p}}$
也就是说,代入的$F^{[0]},F^{[1]},cdots,F^{[p-1]}$都相同,但是系数不同
然后分治就可以了
同样地,最后需要除以len,也就是模数$-1$
代码如下
1 |
using namespace std; |
H – Frightful Formula
算是比较简单的一道题
公式等价于一个表格,往右走有$a$种方法,往下走有$b$种方法,还可以直接从这个格子开始走,有$c$种方法
先不考虑第一行和第一列格子
假设是从$i,j$这个格子开始走的
那么,这个格子需要向右走$n-j$步,向下走$n-i$步
对答案的贡献是
$$
c*a^{n-i}*b^{n-j}*{n-i+n-jchoose n-i}
$$
含义是,从这个格子开始,有$c$种走法,向有走$n-j$次,向下走$n-i$次,在$n-j+n-i$步中,有$n-i$步是往下走的
那么,把这些空白的格子加起来,我们可以得到
$$
begin{aligned}
csum_{i=2}^nsum_{j=2}^na^{n-i}b^{n-j}{n-i+n-jchoose n-i}
&=csum_{i=0}^{n-2}sum_{j=0}^{n-2}a^ib^j{i+jchoose i}\
&=csum_{i=0}^{n-2}frac{a^i}{i!}sum_{j=0}^{n-2}(i+j)!frac{b^j}{j!}
end{aligned}
$$
我们可以枚举$i$,后面的是一个下标差相等的卷积
将多项式逆序一下就可以了
这道题没有给模数,而答案又很大
为了防止丢精度,所以使用MTT
代码如下
1 |
#include <bits/stdc++.h> |
FFT与NTT专题的更多相关文章
- FFT,NTT 专题
学习傅里叶的基本性质及其代码,可以参考大神理解 还有 ACdream 的博客 贴一下NTT的模板: using namespace std; typedef long long ll; int n; ...
- 多项式fft、ntt、fwt 总结
做了四五天的专题,但是并没有刷下多少题.可能一开始就对多项式这块十分困扰,很多细节理解不深. 最简单的形式就是直接两个多项式相乘,也就是多项式卷积,式子是$N^2$的.多项式算法的过程就是把卷积做一种 ...
- 多项式乘法,FFT与NTT
多项式: 多项式?不会 多项式加法: 同类项系数相加: 多项式乘法: A*B=C $A=a_0x^0+a_1x^1+a_2x^2+...+a_ix^i+...+a_{n-1}x^{n-1}$ $B=b ...
- FFT和NTT学习笔记_基础
FFT和NTT学习笔记 算法导论 参考(贺) http://picks.logdown.com/posts/177631-fast-fourier-transform https://blog.csd ...
- fft,ntt总结
一个套路:把式子推成卷积形式,然后用fft或ntt优化求解过程. fft的扩展性不强,不可以在fft函数里多加骚操作--DeepinC T1:多项式乘法 板子题 T2:快速傅立叶之二 另一个板子,小技 ...
- 卷积FFT、NTT、FWT
先简短几句话说说FFT.... 多项式可用系数和点值表示,n个点可确定一个次数小于n的多项式. 多项式乘积为 f(x)*g(x),显然若已知f(x), g(x)的点值,O(n)可求得多项式乘积的点值. ...
- 多项式的基本运算(FFT和NTT)总结
设参与运算的多项式最高次数是n,那么多项式的加法,减法显然可以在O(n)时间内计算. 所以我们关心的是两个多项式的乘积.朴素的方法需要O(n^2)时间,并不够优秀. 考虑优化. 多项式乘积 方案一:分 ...
- 浅谈FFT、NTT和MTT
前言 \(\text{FFT}\)(快速傅里叶变换)是 \(O(n\log n)\) 解决多项式乘法的一个算法,\(\text{NTT}\)(快速数论变换)则是在模域下的,而 \(\text{MTT} ...
- hdu 1402(FFT乘法 || NTT乘法)
A * B Problem Plus Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Other ...
随机推荐
- mod_rewrite是Apache的一个非常强大的功能
mod_rewrite是Apache的一个非常强大的功能,它可以实现伪静态页面.下面我详细说说它的使用方法!对初学者很有用的哦! 1.检测Apache是否支持mod_rewrite 通过php提供的p ...
- Java线程——synachronized关键字的作用(一)
在并发编程中,多线程同时并发访问的资源叫做临界资源,当多个线程同时访问对象并要求操作相同资源时,分割了原子操作就有可能出现数据的不一致或数据不完整的情况,为避免这种情况的发生,我们会采取同步机制,以确 ...
- NOIpDairy
Day 0 水水比赛 Day 1 写写Dp Part1:Dp基础练习 [HNOI2002]公交车路线 秒切,点数这么少,N这么大,目测O(N)+暴力更新 5min写完 P3842 [TJOI2007] ...
- 刷题34. Find First and Last Position of Element in Sorted Array
一.题目说明 题目是34. Find First and Last Position of Element in Sorted Array,查找一个给定值的起止位置,时间复杂度要求是Olog(n).题 ...
- Python语言学习:homework1
'''购物车程序1.启动程序后,让用户输入工资,然后打印商品列表2.允许用户根据商品编号购买商品3.用户选择商品后,检测余额是否够,够就直接扣款,不够就提醒4.可随时退出,退出时,打印已购买商品和余额 ...
- eclipse导入项目报错解决方法
1.导入项目之前,请确认工作空间编码已设置为utf-8:window->Preferences->General->Wrokspace->Text file encoding- ...
- [CTS2019]随机立方体(容斥+组合数学)
这题七次方做法显然,但由于我太菜了,想了一会发现也就只会这么多,而且别的毫无头绪.发现直接做不行,那么,容斥! f[i]为至少i个极值的方案,然后这里需要一些辅助变量,a[i]表示选出i个三维坐标均不 ...
- vue项目中的elementUI的table组件导出成excel表
1.安装依赖:npm install --save xlsx file-saver 2.在放置需要导出功能的组件中引入 import FileSaver from 'file-saver' impor ...
- iso镜像文件的挂载和yum库的搭建
挂载镜像文件 1.上传镜像文件到服务器(或电脑)的某一目录下 如:(/media/rpm_pack/rhel...iso) 2.root 用户下创建镜像文件挂载目录 mkdir /mnt/vcd ...
- Gre封装
在防火墙上连 云时,可以用g0/0/0 在防火墙上不连 云时,一定不用0/0/0 !!!!!!!!! 交换机什么都不配置. FW2: interface GigabitEthernet0/0/0 u ...