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 ...
随机推荐
- Python笔记_第四篇_高阶编程_进程、线程、协程_4.协程
1.协程的概念: 子程序或者子函数,在所有语言中都是层级调用,比如A调用B,再B执行的过程中又可以调用C,C执行完毕返回,B执行返回,最后是A执行完毕返回.是通过栈来实现的,一个线程就是执行一个自称, ...
- Python笔记_第一篇_面向过程_第一部分_4.格式化输入和输出
开始Python编程首先要学习两类最常用(经常出现和使用)输入和输出.学习编程最重要的状态就是“人机交互”,所以这两类函数显得尤其重要. 第一部分 格式化输入 1.1 函:input 语:inpu ...
- maven项目出现Xxx is not a Servlet的问题
应该是tomcat的jar包和maven的jar包冲突 在pom.xml中找到 <dependency> <groupId>org.apache.tomcat</grou ...
- MySQL的InnoDB的幻读问题
MySQL InnoDB事务的隔离级别有四级,默认是“可重复读”(REPEATABLE READ). 未提交读(READ UNCOMMITTED).另一个事务修改了数据,但尚未提交,而本事务中的SEL ...
- 微信小程序-wx.request-路由跳转-数据存储-登录与授权
wx.request 相当于发送ajax请求 官方文档示例代码 wx.request({ url: 'test.php', //仅为示例,并非真实的接口地址 data: { x: '', y: '' ...
- JSON字符串
原因:由于之前接触的JSON都是字符串与数组之间的转化,思维定式认为JSON只是字符串与数组的转化 这个原因是错误的 首先 JSON 是一种语法,用来序列化对象.数组.数值.字符串.布尔值和 null ...
- 解决IntelliJ IDEA Community 社区版 启动Tomcat插件 "Smart Tomcat" NullPointerException 空指针异常
IntelliJ IDEA Community社区版默认是没有Ultimate版的Tomcat Server,这时候就可以使用插件"Smart Tomcat"; 在"Ru ...
- 使用 try-with-resources 优雅关闭资源
桂林SEO:我们知道,在 Java 编程过程中,如果打开了外部资源(文件.数据库连接.网络连接等.redis),我们必须在这些外部资源使用完毕后,手动关闭它们. 因为外部资源不由 JVM 管理,无法享 ...
- Docker相关学习地址
菜鸟教程:http://www.runoob.com/docker/docker-image-usage.html 官方文档:https://docs.docker.com/
- 计量经济与时间序列_ADF单位根检验步骤
1 ADF检验也叫扩展的迪克富勒检验,主要作用是检测序列的平稳性,也是最常用检测序列平稳性的检验方法. 2 何为:平稳性?单位根?(略),见这部分随便的其他内容有讲解.是建模对数据的先决条件. 3 A ...