快速傅里叶变换FFT(模板)
好不容易闲下来总结一下FFT。QAQ
1.DFT:
对于多项式的乘法,DFT给了我们新的思路(点值表达式的O(n)相乘)
对于我们习惯的多项式算法例如多项式A(x)=5x+1和B(x)=2x+2
C(x)=A(x)*B(x)=(5x+1)*(2x+2)=10x2+12x+2
这就是系数表达式,非常地熟悉。
然而这里还有另外一种表达多项式的方法A(x)={(0,1),(2,11)},B(x)={(0,2),(2,6)}
其中(0,1)表示A(x)在x=0时值为1
发现C(x)可以直接由A(x)和B(x)的各个相等x值的表达值相乘得到
也就是说C(x)在x=0是就是等于1*2=2而x=2时的确等于6*11=66嗯嗯
但是有一个问题,那就是C(x)是2次的也就是说至少3个点值才可唯一确定C(x)
但是点值其实是无穷的,我们只是为了简化问题而选择了最少能确定表达式的特殊点
为了唯一确定更高次的表达式
所以A(x)被扩展成{(0,1),(1,6),(2,11)}而B(x)则为{(0,2),(1,4),(2,6)}
这样来表示C(x)就成了C(x)={(0,2),(1,24),(2,66)}表达式就被唯一确定了
我们发现虽然乘法过程是O(n)的但取点值时已经O(n2)了
2.FFT
同样是O(n2)算法
由于卷积模拟过程中的对应是唯一的,也就是说并没有重复,所以说可谓是不可简化的(至少我不会)
而对于DFT的算法其时间主要被消耗在取点值计算的过程中,但我们来仔细观察一下这个步骤发现其运算基本是完全重复的
而我们只需要使用某些玄学的东西就可以在更短的时间内求出这些点值。
其实点值表达式的x可以为复数
这个就是单位复数根Wn(数学内容自行百度),拥有一些美好的性质。
这个数的模长为1且其n次幂为1,理解成一个在复平面旋转的向量好了
拥有折半原理可以缩小问题规模至一半,就是分治搞定好了时间复杂度瞬间降到了O(nlogn)
而递归的常数会将这个算法的优势大大削减,所以我们找到一个最小的大于问题规模的2的次幂来非递归分治处理
这样做就把多项式转化为A(x)={....(wnk,val)..}的形式了
注意精度误差+0.5就好了
以LUOGUP3803为例:
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
const double Pi=acos(-1.0);
struct cp{
double x,y;
cp friend operator + (cp a,cp b)
{
return (cp){a.x+b.x,a.y+b.y};
}
cp friend operator - (cp a,cp b)
{
return (cp){a.x-b.x,a.y-b.y};
}
cp friend operator * (cp a,cp b)
{
return (cp){a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x};
}
}A[],B[];
int R[];
int lim,n,m;
int l;
int cnta,cntb;
void FFt(cp *l,double f)
{
for(int i=;i<lim;i++)
if(i<R[i])
std::swap(l[i],l[R[i]]);
for(int i=;i<lim;i<<=)
{
cp Wn;
Wn=(cp){cos(Pi/i),f*sin(Pi/i)};
for(int j=;j<lim;j+=(i<<))
{
cp W;
W=(cp){1.00,0.00};
for(int k=;k<i;k++,W=W*Wn)
{
cp nx,ny;
nx=l[j+k];
ny=l[i+j+k]*W;
l[j+k]=nx+ny;
l[i+j+k]=nx-ny;
}
}
}
}
int main()
{
l=;
lim=;
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
{
scanf("%lf",&A[i].x);
}
for(int i=;i<=m;i++)
{
scanf("%lf",&B[i].x);
}
while(lim<=(n+m))
{
lim=lim<<;
l++;
}
for(int i=;i<lim;i++)
{
R[i]=(R[i>>]>>)|((i&)<<(l-));
}
FFt(A,1.00);
FFt(B,1.00);
for(int i=;i<=lim;i++)
{
A[i]=A[i]*B[i];
}
FFt(A,-1.00);
for(int i=;i<=n+m;i++)
printf("%d ",(int)(A[i].x/lim+0.5));
return ;
}
快速傅里叶变换FFT(模板)的更多相关文章
- 快速傅里叶变换(FFT)_转载
FFTFFT·Fast Fourier TransformationFast Fourier Transformation快速傅立叶变换 P3803 [模板]多项式乘法(FFT) 参考上文 首 ...
- Algorithm: 多项式乘法 Polynomial Multiplication: 快速傅里叶变换 FFT / 快速数论变换 NTT
Intro: 本篇博客将会从朴素乘法讲起,经过分治乘法,到达FFT和NTT 旨在能够让读者(也让自己)充分理解其思想 模板题入口:洛谷 P3803 [模板]多项式乘法(FFT) 朴素乘法 约定:两个多 ...
- 再探快速傅里叶变换(FFT)学习笔记(其三)(循环卷积的Bluestein算法+分治FFT+FFT的优化+任意模数NTT)
再探快速傅里叶变换(FFT)学习笔记(其三)(循环卷积的Bluestein算法+分治FFT+FFT的优化+任意模数NTT) 目录 再探快速傅里叶变换(FFT)学习笔记(其三)(循环卷积的Blueste ...
- 快速傅里叶变换FFT
多项式乘法 #include <cstdio> #include <cmath> #include <algorithm> #include <cstdlib ...
- [学习笔记] 多项式与快速傅里叶变换(FFT)基础
引入 可能有不少OIer都知道FFT这个神奇的算法, 通过一系列玄学的变化就可以在 $O(nlog(n))$ 的总时间复杂度内计算出两个向量的卷积, 而代码量却非常小. 博主一年半前曾经因COGS的一 ...
- 快速傅里叶变换FFT& 数论变换NTT
相关知识 时间域上的函数f(t)经过傅里叶变换(Fourier Transform)变成频率域上的F(w),也就是用一些不同频率正弦曲线的加 权叠加得到时间域上的信号. \[ F(\omega)=\m ...
- 多项式 之 快速傅里叶变换(FFT)/数论变换(NTT)/常用套路【入门】
原文链接https://www.cnblogs.com/zhouzhendong/p/Fast-Fourier-Transform.html 多项式 之 快速傅里叶变换(FFT)/数论变换(NTT)/ ...
- 快速傅里叶变换(FFT)
扯 去北京学习的时候才系统的学习了一下卷积,当时整理了这个笔记的大部分.后来就一直放着忘了写完.直到今天都腊月二十八了,才想起来还有个FFT的笔记没整完呢.整理完这个我就假装今年的任务全都over了吧 ...
- 基于python的快速傅里叶变换FFT(二)
基于python的快速傅里叶变换FFT(二)本文在上一篇博客的基础上进一步探究正弦函数及其FFT变换. 知识点 FFT变换,其实就是快速离散傅里叶变换,傅立叶变换是数字信号处理领域一种很重要的算法. ...
随机推荐
- 多校第十场1009 CRB and String题解
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5414 题意:给你两个字符串s和t,你能够在字符串s中随意选一个字符c,在该字符c后插入一个字符d(d! ...
- File的getPath()和getAbsolutePath()和getCanonicalPath()的差别
这几个方法是有一次无意的发现,我当时也不知道什么意思,就百度了,查到了一些列子: 原文地址http://www.blogjava.net/dreamstone/archive/2007/08/08/1 ...
- UE4的JSON读写方式<一>
声明:全部权利保留. 转载必须说明出处:http://blog.csdn.net/cartzhang/article/details/41009343 UE4的Json的解析博客地址: http:// ...
- 学习推荐《零起点Python大数据与量化交易》中文PDF+源代码
学习量化交易推荐学习国内关于Python大数据与量化交易的原创图书<零起点Python大数据与量化交易>. 配合zwPython开发平台和zwQuant开源量化软件学习,是一套完整的大数据 ...
- 参考学习《Python学习手册(第4版)》高清中文PDF+高清英文PDF+源代码
看到第38章了,整体感觉解释详细,例子丰富:关于Python语言本身的讲解全面详尽而又循序渐进不断重复,同时详述语言现象背后的机制和原理:除语言本身,还包含编程实践和设计以及高级主题.边看边写代码.不 ...
- 【Django】ORM操作#2
目录 必知必会的13条查询方法 单表查询之神奇的双下划线 一对多 ForeignKey 多对多 ManyToManyField 在Python脚本中调用Django环境 Django终端打印SQL语句 ...
- zip-tar
1.zip 制作压缩文件 (1)格式:zip 压缩文件名 文件1 文件2... zip文件不能用cat查看 (2)选项: -r:用来压缩目录 2.unzip 解压缩文件 (1)格式:unzip 压缩文 ...
- poj Transferring Sylla(怎样高速的推断一个图是否是3—连通图,求割点,割边)
Transferring Sylla 首先.什么是k连通图? k连通图就是指至少去掉k个点使之不连通的图. 题目: 题目描写叙述的非常裸.就是给你一张图要求你推断这图是否是3-连通图. 算法分析: / ...
- 新辰:十种外链终极方法 让SEOer外链之路不再孤独!
大家都知道,外链就是指从别的站点导入到自己站点的链接.导入链接对于新辰站点优化来说是很重要的一个过程.因此,新辰觉得.对于中小型站点来说.外链但是优化的重中之重! 由于也有了"外链专员&qu ...
- php 内置的 html 格式化/美化tidy函数 -- 让你的HTML更美观
php 内置的 html 格式化/美化tidy函数 https://github.com/htacg/tidy-html5 # HTML 格式化 function beautify_html($htm ...