FFT,NTT入门
-1.前置知识
复数
复数单位\(i\):定义为\(i^2=-1\)。\(i\)可以直接参与运算。
复数:形如\(z=a+bi\)的数被称为复数,其中\(a\)称为实部,\(b\)称为虚部。可以发现,当\(b=0\)的时候,\(z\)就是实数。
复平面:建立直角坐标系。对于复数\(z=a+bi\),其在复数平面上的坐标就是\((a,b)\);即横轴表示实部,纵轴表示虚部。另外,一个复数同样可以被表示为复平面上的一个从原点出发的向量。
复数的运算:设\(x=a+bi,y=c+di\),定义如下:
\(x+y=a+bi+c+di=(a+c)+(b+d)i\);
\(x-y=(a+bi)-(c+di)=(a-c)+(b-d)i\);
\(xy=(a+bi)(c+di)=ac+(bc+ad)i+bdi^2=(ac-bd)+(bc+ad)i\)
复数的三角函数形式:前面说到,复数在复平面上即是一个向量。因此我们可以定义复数\(z=a+bi\)的模长为\(|z|=\sqrt{a^2+b^2}\),即向量对应的模长;定义复数\(z=a+bi\)的幅角为向量到实轴正方向的角度为辐角。

反过来,我们可以通过模长\(|z|\)与幅角\(\theta\)来唯一确定一个复数,即\(z=|z|(\cos\theta+i\sin\theta)\)。
因此,对于复数\(x=|x|(\cos\theta_x+i\sin\theta_x),y=|y|(\cos\theta_y+i\sin\theta_y)\),复数的乘法也等价于:
\(xy=|x||y|((\cos\theta_x\cos\theta_y-\sin\theta_x\sin\theta_y)+i(\sin\theta_x\cos\theta_y+\sin\theta_y\cos\theta_x))=|x||y|(\cos(\theta_x+\theta_y)+i\sin(\theta_x+\theta_y))\)
即模长相乘,辐角相加。
单位根
单位根被定义为:方程\(x^n=1\)在复数域内的所有解。
莽了?不用担心,我们先聊一聊单位圆。

可以发现,单位圆实际上就是所有的起点在原点且模长为\(1\)的向量的终点集合。
另一方面,根据复数运算性质,我们发现,所有解的模长一定是\(1\)。
再想一想,解的辐角应该是:\(\frac{2\pi\times 0}{n},\frac{2\pi\times 1}{n},...,\frac{2\pi\times (n-1)}n\),只有这些向量自乘\(n\)次之后,才会落到实轴正半轴上来。
因此,我们得到了结果:\(n\)次单位根有\(n\)个,记为\(\omega_n^{0\sim(n-1)}\),其中\(\omega_n^k\)为一个模长为\(1\),辐角为\(\frac{2\pi\times k}{n}\)的复数。
下图展示了\(n=3\)时的单位根(们):

接下来,有一些关于单位根的重要性质,大家可以按照切蛋糕来理解。
1.\(\omega_n^k=(\omega_n^1)^k\),证明略;
2.\(\omega_n^j\times\omega_n^k=\omega_n^{j+k}\),可用上式证明;
3.\(\omega_{2n}^{2k}=\omega_n^k\)。比如,你一次在蛋糕上切\(\frac18\),那么你切\(4\)块就可以得到半块蛋糕;一次切\(\frac14\),那么你就需要\(2\)块。
4.折半引理:当\(n\)为偶数的时候,\(\omega_{n}^{(k+\frac n2)}=-\omega_n^k\)。其中\(\omega_n^{(k+\frac n2)}=\omega_n^k\times\omega_n^{\frac n2}\),也就是将\(\omega_n^k\)再转半圈之后得到的向量。此时它们模长相等,方向相反,它们就是相反数。
单位根反演
定理:
\]
证明:
当\(n|a\)的时候:
设\(a=nt\),原式中所有\(\omega_n^{ak}=\omega_n^{ntk}=\omega_n^0=1\),因此原式\(=\frac1n\sum_{k=0}^{n-1}1=1\)。
当\(n\not|a\)的时候:
等比数列求和:
\frac1n\sum_{k=0}^{n-1}\omega_n^{ak}&=\frac1n\sum_{k=0}^{n-1}(\omega_n^a)^k\\
&=\frac1n\times \frac{1-\omega_n^{an}}{1-\omega_n^a}\\
&=\frac1n\times \frac{1-1}{1-\omega_n^1}\\
&=0
\end{aligned}\]
于是就证完了。
0.卷积
卷积是定义在函数上的运算。
对于函数\(f(n)\)和\(g(n)\),其卷积\((f*g)(n)\)就是:
\]
我知道你觉得它很没用,所以这里还有离散的表达:
\]
你说计算机处理不了实数?好吧,这里还有最后一个,定义在有限序列\(f\)和\(g\)上的卷积:
\]
是不是很熟悉?这就是我们常见的多项式乘法!
因此,算法竞赛中常常用卷积优化算法 FFT 来进行多项式乘法运算。
1.FFT
FFT,NTT入门的更多相关文章
- FFT/NTT复习笔记&多项式&生成函数学习笔记Ⅰ
众所周知,tzc 在 2019 年(12 月 31 日)就第一次开始接触多项式相关算法,可到 2021 年(1 月 1 日)才开始写这篇 blog. 感觉自己开了个大坑( 多项式 多项式乘法 好吧这个 ...
- FFT \ NTT总结(多项式的构造方法)
前言.FFT NTT 算法 网上有很多,这里不再赘述. 模板见我的代码库: FFT:戳我 NTT:戳我 正经向:FFT题目解题思路 \(FFT\)这个玩意不可能直接裸考的..... 其实一般\(FF ...
- [学习笔记&教程] 信号, 集合, 多项式, 以及各种卷积性变换 (FFT,NTT,FWT,FMT)
目录 信号, 集合, 多项式, 以及卷积性变换 卷积 卷积性变换 傅里叶变换与信号 引入: 信号分析 变换的基础: 复数 傅里叶变换 离散傅里叶变换 FFT 与多项式 \(n\) 次单位复根 消去引理 ...
- FFT/NTT/MTT学习笔记
FFT/NTT/MTT Tags:数学 作业部落 评论地址 前言 这是网上的优秀博客 并不建议初学者看我的博客,因为我也不是很了解FFT的具体原理 一.概述 两个多项式相乘,不用\(N^2\),通过\ ...
- FFT&NTT总结
FFT&NTT总结 一些概念 \(DFT:\)离散傅里叶变换\(\rightarrow O(n^2)\)计算多项式卷积 \(FFT:\)快速傅里叶变换\(\rightarrow O(nlogn ...
- 快速构造FFT/NTT
@(学习笔记)[FFT, NTT] 问题概述 给出两个次数为\(n\)的多项式\(A\)和\(B\), 要求在\(O(n \log n)\)内求出它们的卷积, 即对于结果\(C\)的每一项, 都有\[ ...
- FFT/NTT模板 既 HDU1402 A * B Problem Plus
@(学习笔记)[FFT, NTT] Problem Description Calculate A * B. Input Each line will contain two integers A a ...
- FFT/NTT基础题总结
在学各种数各种反演之前把以前做的$FFT$/$NTT$的题整理一遍 还请数论$dalao$口下留情 T1快速傅立叶之二 题目中要求求出 $c_k=\sum\limits_{i=k}^{n-1}a_i* ...
- $FFT/NTT/FWT$题单&简要题解
打算写一个多项式总结. 虽然自己菜得太真实了. 好像四级标题太小了,下次写博客的时候再考虑一下. 模板 \(FFT\)模板 #include <iostream> #include < ...
随机推荐
- Spring Bean 定义
Bean 定义 被称作 bean 的对象是构成应用程序的支柱.也是由 Spring IoC 容器管理的. bean 是一个被实例化,组装,并通过 Spring IoC 容器所管理的对象. 这些 bea ...
- Spring Boot 教程(2) - Mybatis
Spring Boot 教程 - Mybatis 1. 什么是Mybatis? MyBatis 是一款优秀的持久层框架,它支持自定义 SQL.存储过程以及高级映射.MyBatis 免除了几乎所有的 J ...
- SQL——SQL约束
SQL约束 - 用于限制加入表的数据的类型 可以在创建表时规定约束(通过 CREATE TABLE 语句),或者在表创建之后也可以(通过 ALTER TABLE 语句). NOT NULL ...
- UPD链接实现稳健传输案例
使用的类 DatagramSocket 用于发送数据和接收数据 此类的构造方法: DatagramSocket(); DatagramSocket(端口号); ...
- 关于Java Web结构和SSM框架的理解
Java Web常见的三层结构 表现层:也就是Web层,常见的框架有Spring MVC.Struts2 ,并包括用于展示的界面,如JSP界面:业务层:Service层,专注于业务逻辑的实现:持久层: ...
- 第二章-数据绑定和第一个AnglarJS Web应用
Angularjs中的数据绑定 AngularJS创建实时模板来代替视图,而不是将数据合并进模板之后更新DOM.任何一个独立视图组件中的值都是动态替换的.这个功能可以说是AngularJS中最最重要的 ...
- Java基础语法--java中字符串比较中的坑点
Java 中两个字符串比较大小,可以有两种方式判定,要根据需求选择 == 判定,比较的是两个字符串的内存地址,地址相同则判定为true:反之则反 equals() 判定,比较的是两个字符串的内容,内容 ...
- Qt如何管理组件
转载:清凉简装的博客 解决“要继续此操作,至少需要一个有效且已启用的储存库“问题 1.在Qt安装目录找到组件管理软件MaintenanceTool,双击. 2.点击下一步,出现要继续此操作,至少需要一 ...
- Redis详解(十)------ 从零开始搭建集群
在上一篇博客我们介绍了------Redis哨兵(Sentinel)模式,哨兵模式主要是解决高可用问题,在master节点宕机时,slave节点能够自动切换成为master节点 本篇博客我们来介绍Re ...
- Dubbo源码笔记-服务注册
今天来简单做一下Dubbo服务注册部分源码学习手记. 一.Dubbo配置解析 目前Dubbo最多的用法就是跟Spring集成,既然跟Spring集成,那么,Dubbo对象的实例化都将交由Spring统 ...