Re.FFT
前言
上虽然算是学过了但是实质上还是根本什么都不会 看大佬们的模板去A了模题(手动滑稽)
于是下定决心要理解FFT的代码
一些的证明主要是从算法导论和两位大佬的博客上学的 大佬1 大佬2
在这过程中感觉由于一些证明的东西太琐碎和一直没有找到FFT的要点浪费了很多时间
FFT目的
为了快速求出(在longn的时间复杂度)两个系数表达多项式
经过运算后的系数表达多项式
FFT主要思路
因为发现在多项式以点值表达的时候可以
直接用两个多项式下标相同点值的分别进行运算
可以在线性的时间内完成运算
大大降低了时间复杂度
所以考虑如何快速的将一个系数表达的多项式转化为一个点值表达的多项式再转变回来
最暴力的就是直接把各个不同的x代入求出点值
但是这样显然不合理
我们可以利用单位复根的特殊性质来加速这个过程
(借用下自为风月马前卒大佬的图)

可以发现两个式子只差中间的一个运算符号
这样在求求出第一个的值的时候可以O(1)求出第二个的值
问题就缩小了一半
这样我们就可以像线段树一样O(nlongn)的时间 递归算出整个式子的各个数带进去的值
点值表达转化回系数表达可以通过单位复根的性质 直接修改单位复根的值就可以了
但是我们发现如果直接递归的话 常数会很大 于是某位大佬找出了迭代(递推)的方法
通过蝴蝶操作O(n)预处理一下 可以快速确定如何分为奇偶两种下标的多项式
递推代码(如果FFT代码中的解释没有看懂可以再看下面的补充)
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define C getchar()-48
inline ll read()
{
ll s=0,r=1;
char c=C;
for(;c<0||c>9;c=C) if(c==-3) r=-1;
for(;c>=0&&c<=9;c=C) s=(s<<3)+(s<<1)+c;
return s*r;
}
#define E complex<double>
const int N=;//N记得至少开两倍
const double pi=acos(-1);
int n,m,l,r[N];
E a[N],b[N];
void fft(E *a,int f){
for(int i=0;i<n;i++)if(i<r[i])swap(a[i],a[r[i]]);//交换位置 if为了避免重复交换变回原来的
for(int i=1;i<n;i<<=1){//当前合并两个长度为i的值的集合
E wn(cos(pi/i),f*sin(pi/i));//单位复根 将一个圆分成i部分 因为每次要合并i对下标为奇数和欧素的
for(int p=i<<1,j=0;j<n;j+=p){//当前要合并区间的第一个位置p
E w(1,0);
for(int k=0;k<i;k++,w*=wn){//要合并这个区间的第几个数
E x=a[j+k],y=w*a[j+k+i];
a[j+k]=x+y;a[j+k+i]=x-y; //算出带进去的两个值的结果
}
}
}
}
int main(){
n=read();m=read();
for(int i=0;i<=n;i++)a[i]=read();
for(int i=0;i<=m;i++)b[i]=read();
m+=n;for(n=1;n<=m;n<<=1)l++;//乘运算后的长度至少为n+m 运算要求为2的整次幂
for(int i=0;i<n;i++)r[i]=(r[i>>1]>>1)|((i&1)<<(l-1));//蝴蝶操作
fft(a,1);fft(b,1);//转化为点值表达
for(int i=0;i<=n;i++)a[i]=a[i]*b[i];//O(n)运算
fft(a,-1);//转化为系数表达
for(int i=0;i<=m;i++)printf("%d ",(int)(a[i].real()/n+0.5));
}
补充
如果想要更好的体验就点链接吧(貌似要先登录):传送门
辛辛苦苦画了一晚上


Re.FFT的更多相关文章
- 并行计算提升32K*32K点(32位浮点数) FFT计算速度(4核八线程E3处理器)
对32K*32K的随机数矩阵进行FFT变换,数的格式是32位浮点数.将产生的数据存放在堆上,对每一行数据进行N=32K的FFT,记录32K次fft的时间. 比较串行for循环和并行for循环的运行时间 ...
- 【BZOJ-2179&2194】FFT快速傅里叶&快速傅里叶之二 FFT
2179: FFT快速傅立叶 Time Limit: 10 Sec Memory Limit: 259 MBSubmit: 2978 Solved: 1523[Submit][Status][Di ...
- 为什么FFT时域补0后,经FFT变换就是频域进行内插?
应该这样来理解这个问题: 补0后的DFT(FFT是DFT的快速算法),实际上公式并没变,变化的只是频域项(如:补0前FFT计算得到的是m*2*pi/M处的频域值, 而补0后得到的是n*2*pi/N处的 ...
- FFT NNT
算算劳资已经多久没学新算法了,又要重新开始学辣.直接扔板子,跑...话说FFT算法导论里讲的真不错,去看下就懂了. //FFT#include <cstdio> #include < ...
- CC countari & 分块+FFT
题意: 求一个序列中顺序的长度为3的等差数列. SOL: 对于这种计数问题都是用个数的卷积来进行统计.然而对于这个题有顺序的限制,不好直接统计,于是竟然可以分块?惊为天人... 考虑分块以后的序列: ...
- ECF R9(632E) & FFT
Description: 上一篇blog. Solution: 同样我们可以用fft来做...就像上次写的那道3-idoit一样,对a做k次卷积就好了. 同样有许多需要注意的地方:我们只是判断可行性, ...
- fft练习
数学相关一直都好弱啊>_< 窝这个月要补一补数学啦, 先从基础的fft补起吧! 现在做了 道. 窝的fft 模板 (bzoj 2179) #include <iostream> ...
- FFT时域与频域的关系,以及采样速率与采样点的影响
首先对于FFT来说,输入的信号是一个按一定采样频率获得的信号序列,而输出是每个采样点对应的频率的幅度(能量). 下面详细分析: 在FFT的输出数据中,第一个值是直流分量的振幅(这样对应周期有无穷的可能 ...
- 【玩转单片机系列002】 如何使用STM32提供的DSP库进行FFT
前些日子,因为需要在STM32F103系列处理器上,对采集的音频信号进行FFT,所以花了一些时间来研究如何高效并精确的在STM32F103系列处理器上实现FFT.在网上找了很多这方面的资料做实验并进行 ...
- FFT
void FFT(complex a[],int n,int fl){ ,j=n/;i<n;i++){ if (i<j) {complex t=a[i];a[i]=a[j];a[j]=t; ...
随机推荐
- oracle学习笔记(五) SQL操作符
SQL操作符 算术操作符:+加,-减,*乘,/除 比较操作符: <,>,=,!=,<>,<=,>= 常用的判断,<>和!=相同 between $low ...
- Django学习之九: auth 认证组件
目录 Django auth 认证组件 配置使用auth组件及其中间件 request.user 可以直接在template模版中使用 auth组件常用api 获取认证model类 认证检测装饰器@l ...
- 学习笔记—JVM
JVM结构 JVM总体结构图 类加载子系统与方法区: 类加载子系统负责从文件系统和网络中加载Class信息,加载的类信息存放于一块称为方法区的内存空间. 除了类信息外,方法区中还可能会存放运行时常量池 ...
- ES6基础(二)
一.ES6字符串扩展 字符串模板 在传统的JavaScript语言中,输出模板通常是这样写的. 上面这种写法繁琐不方便,于是ES6中引入了字符串模板解决这个问题. 用反引号(`)标识.他可以当做普通字 ...
- 在虚拟机中搭建qduoj(一)——准备工作
为缩减篇幅,已略去ubuntu镜像下载.虚拟机(VirtualBox.VMware)安装等操作,若有疑问请搜索相关教程. 1.虚拟机系统安装 本教程使用Ubuntu16.04 server版本(des ...
- IGP和BGP路由协议配合降低非核心路由器的路由容量的实验与总结
IGP和BGP路由协议配合降低非核心路由器的路由容量的实验与总结 一.结论 通过eBGP协议,可以显著降低对非核心路由器的路由容量要求,因为核心路由器的数量明显少于非核心路由器,所以,通过此措施既可以 ...
- 如何简单的构建Android?
原文链接:https://fernandocejas.com/2014/09/03/architecting-android-the-clean-way/ 过去的几个月中,在Tuenti上与同行例 ...
- 使用免费 mongodb数据库 + 免费node.js服务器搭建小程序接口
由于微信的小程序只支持不带端口的域名接口,不支持IP地址和接口,所以我们需要映射到80端口并绑定备案过的域名才能被微信小程序访问到.简单点就是接口需要 https 协议才行,找了许久的免费的数据库与n ...
- Delphi 字符串转日期,强大到窒息,VarToDateTime 解决了 困扰很久的小问题
procedure THRForm.Button1Click(Sender: TObject); var D:TDateTime; s:string; begin D:=VarToDateTime(' ...
- 数字信号处理专题(2)——利用FPGA进行基本运算及特殊函数定点运算
一.前言 FPGA以擅长高速并行数据处理而闻名,从有线/无线通信到图像处理中各种DSP算法,再到现今火爆的AI应用,都离不开卷积.滤波.变换等基本的数学运算.但由于FPGA的硬件结构和开发特性使得其对 ...