好不容易闲下来总结一下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. BZOJ 1579 道路升级 Dijkstra

    思路: 这道题 不能把所有边都建出来 会MLE的!!! oh gosh 其实不建所有的边 用的时候再调就行了-.(也没啥区别) //By SiriusRen #include <queue> ...

  2. 版本控制Git(1)——理解暂存区

    一.svn和Git的比较 我们都知道传统的源代码管理都是以服务器为中心的,每个开发者都直接连在中间服务器上, 本地修改,然后commit到svn服务器上.这种做法看似完美,但是有致命的缺陷. 1. 开 ...

  3. ES6特性-带标签的模板字符串(tagged template)

    tagged template: 加在模板字符串前面加一个标签(函数). let dessert = = '甜品' drink = '茶' let breakfast = kitchen`今天的早餐是 ...

  4. 运输层协议——UDP

    UDP概述: UDP只是做了运输层协议能做的最少工作,仅做了复用/分解,少量的差错检验. UDP是无连接的. UDP优点: 关于何时.发送什么数据的应用层控制更为精细:TCP在拥堵时会遏制发送方的发送 ...

  5. route---设置Linux内核中的网络路由表

    route命令用来显示并设置Linux内核中的网络路由表,route命令设置的路由主要是静态路由.要实现两个不同的子网之间的通信,需要一台连接两个网络的路由器,或者同时位于两个网络的网关来实现. 在L ...

  6. JAVA实现排队论

    转载请注明出处:http://blog.csdn.net/xiaojimanman/article/details/50401727 http://www.llwjy.com/blogdetail/3 ...

  7. Objective-C method及相关方法分析

    ## Objective-C method及相关方法分析 转载请注名出处 [http://blog.csdn.net/uxyheaven](http://blog.csdn.net/uxyheaven ...

  8. Mysql第八天 分区与分表

    分区表 主要提供例如以下的特性,或者适合如此场景: 数据量非常大, 或者仅仅有表中最后的部分有热点数据.其它均为历史数据 分区表数据更easy维护,能够对独立的分区删除等操作 分区表的数据能够分布在不 ...

  9. JavaWeb-04(BOM&amp;DOM)

    JavaWeb-04 JavaWeb-BOM&DOM BOM 一.知识回想 * BOM 概述 * BOM 的各个对象 * window对象 innerHeight,innerWidth doc ...

  10. OL记载Arcgis Server切片

    概述: 本文讲述怎样在OpenLayers中调用Arcgis Server切片并显示. 思路: 在OpenLayers中载入Arcgis Server切片用XYZ图层,Arcgis Server的切片 ...