好不容易闲下来总结一下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(模板)的更多相关文章

  1. 快速傅里叶变换(FFT)_转载

    FFTFFT·Fast  Fourier  TransformationFast  Fourier  Transformation快速傅立叶变换 P3803 [模板]多项式乘法(FFT) 参考上文 首 ...

  2. Algorithm: 多项式乘法 Polynomial Multiplication: 快速傅里叶变换 FFT / 快速数论变换 NTT

    Intro: 本篇博客将会从朴素乘法讲起,经过分治乘法,到达FFT和NTT 旨在能够让读者(也让自己)充分理解其思想 模板题入口:洛谷 P3803 [模板]多项式乘法(FFT) 朴素乘法 约定:两个多 ...

  3. 再探快速傅里叶变换(FFT)学习笔记(其三)(循环卷积的Bluestein算法+分治FFT+FFT的优化+任意模数NTT)

    再探快速傅里叶变换(FFT)学习笔记(其三)(循环卷积的Bluestein算法+分治FFT+FFT的优化+任意模数NTT) 目录 再探快速傅里叶变换(FFT)学习笔记(其三)(循环卷积的Blueste ...

  4. 快速傅里叶变换FFT

    多项式乘法 #include <cstdio> #include <cmath> #include <algorithm> #include <cstdlib ...

  5. [学习笔记] 多项式与快速傅里叶变换(FFT)基础

    引入 可能有不少OIer都知道FFT这个神奇的算法, 通过一系列玄学的变化就可以在 $O(nlog(n))$ 的总时间复杂度内计算出两个向量的卷积, 而代码量却非常小. 博主一年半前曾经因COGS的一 ...

  6. 快速傅里叶变换FFT& 数论变换NTT

    相关知识 时间域上的函数f(t)经过傅里叶变换(Fourier Transform)变成频率域上的F(w),也就是用一些不同频率正弦曲线的加 权叠加得到时间域上的信号. \[ F(\omega)=\m ...

  7. 多项式 之 快速傅里叶变换(FFT)/数论变换(NTT)/常用套路【入门】

    原文链接https://www.cnblogs.com/zhouzhendong/p/Fast-Fourier-Transform.html 多项式 之 快速傅里叶变换(FFT)/数论变换(NTT)/ ...

  8. 快速傅里叶变换(FFT)

    扯 去北京学习的时候才系统的学习了一下卷积,当时整理了这个笔记的大部分.后来就一直放着忘了写完.直到今天都腊月二十八了,才想起来还有个FFT的笔记没整完呢.整理完这个我就假装今年的任务全都over了吧 ...

  9. 基于python的快速傅里叶变换FFT(二)

    基于python的快速傅里叶变换FFT(二)本文在上一篇博客的基础上进一步探究正弦函数及其FFT变换. 知识点  FFT变换,其实就是快速离散傅里叶变换,傅立叶变换是数字信号处理领域一种很重要的算法. ...

随机推荐

  1. vue11 vue实例方法

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. 多路径软件常用操作(MPIO)

    一:查看存储盘的路径 1. 查看MPIO的存储盘的路径 # lspath (适用于所有存储的MPIO路径查询) # mpio_get_config -Av (适用于DS3K/DS4K的MPIO路径查询 ...

  3. SQL语句查询数据库所有表和所有字段的详细信息(包括表描述和字段描述)

    select (case then ddd.value else '' end ) as "表名(中文)" --如果表名相同就返回空 , (case then d.name els ...

  4. 如何利用Python词云和wordart可视化工具对朋友圈数据进行可视化展示

    大前天我们通过Python网络爬虫对朋友圈的数据进行了抓取,感兴趣的朋友可以点击进行查看,如何利用Python网络爬虫抓取微信朋友圈的动态(上)和如何利用Python网络爬虫爬取微信朋友圈动态——附代 ...

  5. Vim使用心得总结

    基本快捷键 v 进入可视模式 i / a 光标前/后插入模式 I / A 行首/末插入模式 Crtl+c 进入命令模式 Crtl+v 进入块可视模式 Q 进入EX模式 gh 进入选择模式 u 撤销 U ...

  6. 10G安装DataGuard

    最后更新时间:2013年8月4日,星期日 ★ oracle 10G安装环境 数据库软件安装环境不详细描述,网上到处有这方面资料,下面只简单描述下. 也可参考官方文档: http://docs.orac ...

  7. tee---将数据重定向到文件,

    tee命令用于将数据重定向到文件,另一方面还可以提供一份重定向数据的副本作为后续命令的stdin.简单的说就是把数据重定向到给定文件和屏幕上. 存在缓存机制,每1024个字节将输出一次.若从管道接收输 ...

  8. 小米开源便签Notes-源码研究(1)-导出功能整体思路

    NotesListActivity是入口Activity. 响应菜单事件,我的手机是"左键菜单".如果菜单项的ID是"R.id.menu_export_text" ...

  9. java web应用调用python深度学习训练的模型

    之前参见了中国软件杯大赛,在大赛中用到了深度学习的相关算法,也训练了一些简单的模型.项目线上平台是用java编写的web应用程序,而深度学习使用的是python语言,这就涉及到了在java代码中调用p ...

  10. 编程里的API是什么意思?

    API(Application Programming Interface,应用程序编程接口)是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力,而又无需访问源码 ...