首先说一下我用FFT做什么,我要做的是多项式乘法,或者说,加速多项式乘法。
  考虑多项式A(x)=∑j=0n−1ajxjA(x)=\sum\limits_{j=0}^{n-1}a_jx^j,它一共有nn项,我们称它的次数界为nn。假设我们有两个次数界为nn的多项式A(x)A(x)和B(x)B(x),要求它们的和是非常简单的,只需要将对应的系数相加,复杂度为O(n)O(n)。如果要求他们的积,则需要将A(x)A(x)的每一项和B(x)B(x)的每一项相乘,复杂度为O(n2)O(n^2),这就显得有点慢了。
  上面提到的多项式表示方法A(x)=∑j=0n−1ajxjA(x)=\sum\limits_{j=0}^{n-1}a_jx^j称为系数表示,实际上它还有另一种表示方法叫点值表示。我们取nn个不同的值x0x_0,x1x_1,…,xn−1x_{n-1}代入多项式,可以得到nn个点(x0,A(x0))(x_0,A(x_0)),…,(xn−1,A(xn−1))(x_{n-1},A(x_{n-1}))。这nn个点可以确定一个唯一的原多项式(至于为什么,就不细说了)。
假设我们可以迅速在多项式的系数表示和点值表示间转换,就可以迅速完成多项式乘法。回到那个多项式A(x)A(x),我们把xx的取值范围扩展到复数,ωn\omega_n表示nn(假设为2的整数幂)次单位复数根,恰当地选择多项式中xx的取值,使其分别等于ω1n,ω2n,...,ωnn\omega_n^1,\omega_n^2,...,\omega_n^n,就可以利用一些性质,递归地计算,进行加速。

下面放出一道题:Thief in a Shop
  可以这样理解题意:有nn个数a1a_1~ana_n,从中选取kk个(可重复),问得到的和可以是多少。我们可以把它转化为一个多项式,若存在aia_i,则多项式第aia_i项的系数为11,否则为00。这样一来,两个多项式的乘积中,系数不为00的项就是k=2k=2时的解,继续乘下去,可以得到k=3,4,5...k=3,4,5...的解。
  于是,我们就需要FFT来迅速完成多项式乘法,同时利用倍增,只进行log2(k)log_2(k)次乘法。注意每次乘完之后,要对那个列向量规整一下,避免迭代过程累积误差。
  下面的代码可以作为模板。。

#include <bits/stdc++.h>using namespace std;#define ll long longconst double eps = 0.5;
const double PI = acos(-1.0);struct Complex{double r,i;Complex(double r=0.0,double i=0.0):r(r),i(i){}Complex operator+(const Complex& c)const{return Complex(r+c.r,i+c.i);}Complex operator-(const Complex& c)const{return Complex(r-c.r,i-c.i);}Complex operator*(const Complex& c)const{return Complex(r*c.r-i*c.i,r*c.i+i*c.r);}
};void change(Complex y[],int len){for(int i=1,j=len>>1;i<len-1;i++){if(i<j){swap(y[i],y[j]);}int k = len>>1;while(j>=k){j -= k;k >>= 1;}if(j<k){j += k;}}
}void fft(Complex y[],int len,int on){change(y,len);for(int i=2;i<=len;i<<=1){Complex wn(cos(-on*2*PI/i),sin(-on*2*PI/i));for(int j=0;j<len;j+=i){Complex w(1,0);for(int k=j;k<j+i/2;k++){Complex u = y[k];Complex t = w*y[k+i/2];y[k] = u + t;y[k+i/2] = u - t;w = w * wn;}}}if(on == -1){for(int i=0;i<len;i++){y[i].r /= len;}}
}int lowbit(int x){return x&(-x);
}int fix(Complex *y,int l){while(l && y[l-1].r<eps ){l--;}for(int i=0;i<l;i++){Complex &c = y[i];if(c.r>eps){c.r = 1;}else{c.r = 0;}c.i = 0;}for(int i=l;i<1024*1024;i++){Complex &c = y[i];c.r = c.i = 0;} return l+1;
}void Print(Complex *y,int l){for(int i=0;i<l;i++){if(y[i].r>eps){cout<<i<<" ";}}cout<<endl;
}int mul(Complex *v1,int l1,Complex *v2,int l2,Complex *res){l1 = fix(v1,l1);l2 = fix(v2,l2);int sz = 2*max(l1,l2);while(sz!=lowbit(sz)){sz+=lowbit(sz);}l1 = l2 = sz;fft(v1,l1,1);fft(v2,l2,1);for(int i=0;i<sz;i++){res[i] = (v1[i]*v2[i]);}fft(res,sz,-1);return sz;
}Complex v[1024*1024];
Complex v2[1024*1024];
Complex ans[1024*1024];int main(){ int n,k;cin>>n>>k;for(int i=1;i<=n;i++){int num;cin>>num;v[num].r = 1.0;}int sz = 1024;ans[0].r = 1;while(k){if(k&1){for(int i=0;i<sz;i++){v2[i] = v[i];}mul(v2,sz,ans,sz,ans);      }for(int i=0;i<sz;i++){v2[i] = v[i];}sz = mul(v,sz,v2,sz,v);k>>=1;}sz = fix(ans,sz);for(int i=0;i<sz;i++){if(ans[i].r > eps){printf("%d ",i);}}return 0;
}

快速傅里叶变换(FFT)相关推荐

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

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

  2. 基于python的快速傅里叶变换FFT(一)

    基于python的快速傅里叶变换FFT(一) FFT可以将一个信号变换到频域.有些信号在时域上是很难看出什么特征的,但是如果变换到频域之后,就很容易看出特征了.这就是很多信号分析采用FFT变换的原因. ...

  3. MIT 线性代数 Linear Algebra 26:复矩阵,傅里叶矩阵, 快速傅里叶变换 FFT

    这一讲我们来讲一下复矩阵.线性代数中,复矩阵是避免不了的话题,因为一个简单实矩阵都有可能有复数特征值. 复矩阵 我们着重看一下复矩阵和实矩阵在运算上的区别. 距离 首先,一个复数向量的的距离求法发生了 ...

  4. Java中实现快速傅里叶变换FFT

    Java中实现快速傅里叶变换FFT 一.概述 1.傅里叶变换(FT) 2.离散傅里叶变换(DFT) 3.快速傅里叶变换(FFT) 1)单位根 2)快速傅里叶变换的思想 3)蝶形图 4)快速傅里叶变换的 ...

  5. OpenCV快速傅里叶变换(FFT)用于图像和视讯流的模糊检测

    OpenCV快速傅里叶变换(FFT)用于图像和视频流的模糊检测 翻译自[OpenCV Fast Fourier Transform (FFT) for blur detection in images ...

  6. Matlab如何进行利用离散傅里叶变换DFT (快速傅里叶变换FFT)进行频谱分析

    文章目录 1. 定义 2. 变换和处理 3. 函数 4. 实例演示 例1:单频正弦信号(整数周期采样) 例2:单频正弦信号(非整数周期采样) 例3:含有直流分量的单频正弦信号 例4:正弦复合信号 例5 ...

  7. 快速傅里叶变换FFT进行频谱分析(matlab)

    快速傅里叶变换FFT进行频谱分析(matlab) 本章摘要:FFT是离散傅立叶变换的快速算法,可以将一个信号变换到频域.有些信号在时域上是很难看出什么特征的,但是如果变换到频域之后,就很容易看出特征了 ...

  8. Java编程实现快速傅里叶变换FFT

    快速傅里叶变换的时间复杂度分析 1 快速傅里叶变换FFT 1.1 理论分析 1.1.1 离散傅里叶变换 1.1.2 快速傅里叶变换 1.2 编程实现 1.2.1 算法思想 1.2.2 实验结果 1 快 ...

  9. 快速傅里叶变换FFT C语言实现 可用于嵌入式系统进行模拟采样频谱分析

    快速傅里叶变换C语言实现 模拟采样进行频谱分析 FFT是DFT的快速算法用于分析确定信号(时间连续可积信号.不一定是周期信号)的频率(或相位.此处不研究相位)成分,且傅里叶变换对应的 ω \omega ...

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

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

最新文章

  1. Servlet第六篇【Session介绍、API、生命周期、应用、与Cookie区别】
  2. PO,VO,DAO,BO,POJO 之间的区别你懂吗?
  3. orale用户密码过期处理
  4. c#串口程序接收数据并打印_C#程序可打印各种数据类型的大小
  5. java 整数存储为2进制补码形式
  6. 计算机软件录音注意事项,录音笔使用注意事项
  7. Masterlab 1.1 发布,基于敏捷开发的项目管理工具
  8. ELK实践(二):收集Nginx日志
  9. 微软不愿意提及的软肋:Win10的语音识别
  10. Linux创建与删除用户
  11. 微信公众号weui的使用
  12. 女生学Java软件开发好就业吗
  13. 桌面计算机怎么设置时钟同步,电脑进入屏保后怎么设定让时间显示在萤幕上
  14. 卡西欧计算机能开根号吗,考研计算器怎么开根号
  15. OC Foundation框架 数组
  16. 人脸识别的流行用途有哪些
  17. python ttk.notebook_python – 删除Ttk Notebook标签虚线
  18. 哈希表构造与处理冲突方法
  19. 一年中的某周转换成当前周星期一和星期日的日期
  20. 爬虫的智能化解析之使用Diffbot自动解析页面

热门文章

  1. 随机过程| 特征函数篇
  2. 论文撰写(1)——撰写摘要、关键词和引言
  3. 手动解决浏览器主页被劫持的问题
  4. c# hdf5 写string_C# hdf5 文件操作入门
  5. 求一元二次方程的根(C语言实现)
  6. class Complex
  7. 如何用PHP实现上传图片功能
  8. 如何用OKR提高下属执行力
  9. matlab对信号进行AM调制与解调(仿真)
  10. 天猫店铺基础知识分享