好不容易闲下来总结一下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. java音乐播放之IO流处理

    这个类仅仅能一直播放.知道音乐结束. 比AudioCilp要好一点. import java.io.*; import javax.sound.sampled.*; public class Test ...

  2. PHP长整型在32位系统中强制转化溢出

    CleverCode近期遇到一个PHP项目整形转化问题,mysql有一个字段id是bigint的,里面有长整型,如id = 5147486396.可是php代码因为历史原因却部署在多台机器中,当中A机 ...

  3. 美团实习生电面之谈(成功拿到offer)

    3月底进行了美团的一次实习生面试(Java研发project师).当时顺利的通过一面.以下是我的一面: 1.CPU由哪些部分组成 2.线程和进程的差别 3.Java类载入机制 4.怎样实现一个字符串的 ...

  4. HDU 4572 Bottles Arrangement

    具体的证明:点击打开链接 我的想法: 要想保证题目所说 构造最小行的和,仅仅能是这样的情况 .....      m-3  m-2  m-1  m    |   m  m-1  m-2  m-3   ...

  5. 动态网页爬取样例(WebCollector+selenium+phantomjs)

    目标:动态网页爬取 说明:这里的动态网页指几种可能:1)须要用户交互,如常见的登录操作:2)网页通过JS / AJAX动态生成.如一个html里有<div id="test" ...

  6. Linux常用截图软件

    1.Gnome-screenshot 是一款 GNOME 截图工具,顾名思义,它是一款用来对整个屏幕.一个特定的窗口或者用户所定义一些其他区域进行捕获的工具.该工具提供了几个其他的功能,包括对所捕获的 ...

  7. 重新安装python2.6 和 yum (不可以直接安装yum yum 依赖于python2.6)

    (升级或卸载Python导致 yum出错) 一: 升级python导致yum出错 1. cd  /usr/bin/yum 2.  #!/usr/bin/python 修改为    #!/usr/bin ...

  8. ZOJ 2532 Internship

    Internship Time Limit: 5000ms Memory Limit: 32768KB This problem will be judged on ZJU. Original ID: ...

  9. [Android实例] 高速静默更新,低流量耗费,让APP活跃起来!

    大家好.我是csdn的新人,给大家带来一个做了一个星期的SDK,能够实现将Android APP碎片化管理.自由更新,实时更新,低流量耗费的更新~~ Zag Whim Renewal A system ...

  10. js---05 自定义属性

    <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content ...