快速傅里叶变换模板题

算法理解请看《算法导论》第30章《多项式与快速傅里叶变换》,至于证明插值唯一性什么的看不懂也没关系啦~只要明白这个过程是怎么算的就ok。

递归版:(4252ms  23468kb)

 //UOJ 34 递归版
#include<cmath>
#include<vector>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<complex>
#include<iostream>
#include<algorithm>
#define rep(i,n) for(int i=0;i<n;++i)
#define F(i,j,n) for(int i=j;i<=n;++i)
#define D(i,j,n) for(int i=j;i>=n;--i)
using namespace std;
const int N=;
void read(int &v){
v=;int sign=; char ch=getchar();
while(ch<'' || ch>'') {if (ch=='-') sign=-; ch=getchar();}
while(ch>=''&&ch<=''){v=v*+ch-''; ch=getchar();}
v*=sign;
}
/****************tamplate***********************/
const double PI=acos(-);
typedef complex<double> comp;
comp a[N],b[N],c[N];
void FFT(comp a[],int n,int type){
if (n==) return;
int i;
comp y0[n>>],y1[n>>];
for(int i=;i<n;i+=)
y0[i>>]=a[i],y1[i>>]=a[i+];
FFT(y0,n>>,type); FFT(y1,n>>,type);
comp w0( cos(type**PI/n) , sin(type**PI/n) ), w(,);
for(i=;i<(n>>);i++,w*=w0)
a[i]=y0[i]+w*y1[i],a[i+(n>>)]=y0[i]-w*y1[i];
}
int main(){
int i,temp,n,m;
read(n); read(m);
int x;
F(i,,n) read(x),a[i].real()=x;
F(i,,m) read(x),b[i].real()=x;
for(temp=;temp<=m+n;temp<<=);
FFT(a,temp,); FFT(b,temp,);
rep(i,temp) c[i]=a[i]*b[i];
FFT(c,temp,-);
for(int i=;i<=m+n;++i)
printf("%d ",int(c[i].real()/temp+0.5));
puts("");
return ;
}

迭代版:(1228ms 48088kb)(空间浪费了,其实用不了这么大)

 //UOJ 34 迭代版
#include<cmath>
#include<vector>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<complex>
#include<iostream>
#include<algorithm>
#define rep(i,n) for(int i=0;i<n;++i)
#define F(i,j,n) for(int i=j;i<=n;++i)
#define D(i,j,n) for(int i=j;i>=n;--i)
using namespace std;
const int N=;
void read(int &v){
v=;int sign=; char ch=getchar();
while(ch<'' || ch>'') {if (ch=='-') sign=-; ch=getchar();}
while(ch>=''&&ch<=''){v=v*+ch-''; ch=getchar();}
v*=sign;
}
/****************tamplate***********************/
const double pi=acos(-);
typedef complex<double> comp;
comp a[N],b[N],c[N];
int n,m;
void FFT(comp *a,int n,int type){
for(int i=,j=;i<n-;i++){//j初始为i-1的位逆序置换?……每次算出i的位逆序置换j,下一次从j开始找(二进制加法)
//只改变1~n-2,0和n-1位置不变
for(int s=n;j^=s>>=,~j&s;);//
if (i<j) swap(a[i],a[j]);
}
for(int m=;m<n;m<<=){
double u=pi/m*type; comp wm(cos(u),sin(u));
for(int k=;k<n;k+=(m<<) ){
comp w(,);
for(int j=;j<m;j++){
comp &A=a[k+j+m],&B=a[k+j],t=w*A;
A=B-t; B=B+t; w=w*wm;
}
}
}
if (type==-) rep(i,n) a[i].real()/=n;
} int main(){
#ifndef ONLINE_JUDGE
freopen("FFT.in","r",stdin);
#endif
read(n); read(m);
int k=;
for(k=;k<=n||k<=m;k<<=); k<<=;
int x;
F(i,,n) read(x),a[i].real()=x;
F(i,,m) read(x),b[i].real()=x;
FFT(a,k,); FFT(b,k,);
rep(i,k) c[i]=a[i]*b[i];
FFT(c,k,-);
F(i,,n+m) printf("%d ",int(c[i].real()+0.5));
return ;
}

位逆序置换:(orz trz爷)(27~30行)

TRZ:比如我们要把一个二进制数加一,不是从最低位开始找到一个0,把它变成1,它之后的都变0嘛?那么现在我们有了i的位逆序表示,要求i+1的,不就是从最高位找0嘛,那个循环就是干这个事的。

【UOJ】【34】多项式乘法的更多相关文章

  1. [UOJ#34]多项式乘法

    [UOJ#34]多项式乘法 试题描述 这是一道模板题. 给你两个多项式,请输出乘起来后的多项式. 输入 第一行两个整数 n 和 m,分别表示两个多项式的次数. 第二行 n+1 个整数,分别表示第一个多 ...

  2. ●UOJ 34 多项式乘法

    题链: http://uoj.ac/problem/34 题解: FFT入门题. (终于接触到迷一样的FFT了) 初学者在对复数和单位根有简单了解的基础上,可以直接看<再探快速傅里叶变换> ...

  3. UOJ#34. 多项式乘法(NTT)

    这是一道模板题. 给你两个多项式,请输出乘起来后的多项式. 输入格式 第一行两个整数 nn 和 mm,分别表示两个多项式的次数. 第二行 n+1n+1 个整数,表示第一个多项式的 00 到 nn 次项 ...

  4. 【刷题】UOJ #34 多项式乘法

    这是一道模板题. 给你两个多项式,请输出乘起来后的多项式. 输入格式 第一行两个整数 \(n\) 和 \(m\) ,分别表示两个多项式的次数. 第二行 \(n+1\) 个整数,表示第一个多项式的 \( ...

  5. UOJ 34 多项式乘法 FFT 模板

    这是一道模板题. 给你两个多项式,请输出乘起来后的多项式. 输入格式 第一行两个整数 nn 和 mm,分别表示两个多项式的次数. 第二行 n+1n+1 个整数,表示第一个多项式的 00 到 nn 次项 ...

  6. 2018.11.14 uoj#34. 多项式乘法(ntt)

    传送门 今天学习nttnttntt. 其实递归方法和fftfftfft是完全相同的. 只不过fftfftfft的单位根用的是复数中的东西,而nttnttntt用的是数论里面有相同性质的原根. 代码: ...

  7. 2018.11.14 uoj#34. 多项式乘法(fft)

    传送门 NOIpNOIpNOIp爆炸不能阻止我搞oioioi的决心 信息技术课进行一点康复训练. fftfftfft板题. 代码: #include<bits/stdc++.h> usin ...

  8. UOJ 34 多项式乘法 ——NTT

    [题目分析] 快速数论变换的模板题目. 与fft的方法类似,只是把复数域中的具有循环性质的单位复数根换成了模意义下的原根. 然后和fft一样写就好了,没有精度误差,但是跑起来比较慢. 这破题目改了好长 ...

  9. UOJ 34: 多项式乘法(FFT模板题)

    关于FFT 这个博客的讲解超级棒 http://blog.miskcoo.com/2015/04/polynomial-multiplication-and-fast-fourier-transfor ...

  10. [UOJ 0034] 多项式乘法

    #34. 多项式乘法 统计 描述 提交 自定义测试 这是一道模板题. 给你两个多项式,请输出乘起来后的多项式. 输入格式 第一行两个整数 nn 和 mm,分别表示两个多项式的次数. 第二行 n+1n+ ...

随机推荐

  1. XML DOM 循环(foreach)读取PHP数据 和 PHP 编写 XML DOM 【转载】

    用 PHP 读取和编写可扩展标记语言(XML)看起来可能有点恐怖.实际上,XML 和它的所有相关技术可能是恐怖的,但是用 PHP 读取和编写 XML 不一定是项恐怖的任务.首先,需要学习一点关于 XM ...

  2. OC3_协议关键字

    // // Student.h // OC3_协议关键字 // // Created by zhangxueming on 15/6/24. // Copyright (c) 2015年 zhangx ...

  3. [zz] Install VSFTP

    The first two letters of vsftpd stand for "very secure" and the program was built to have ...

  4. log tag

        Media Player MediaPlayerService     NuPlayerDecoder     NuPlayer      MediaFocusControl       Ac ...

  5. Java应用短信猫

    首先确定短信猫正常连接到主机,并安装SIM卡.先用超级终端测试短息猫能不能用.安装minicom:#sudo apt-get install minicom安装完成后,执行#sudo minicom ...

  6. 基于ArcGIS API for JavaScript的统计图表实现

    感谢原作者分享:https://github.com/shevchenhe/ChartLayer,在使用的过程中,需要自己进行调试修改,主要还是_draw函数,不同的ArcGIS JS API函数有差 ...

  7. CentOS6.4安装LAMP环境

    1.配置防火墙,开放80.3306端口 vi /etc/sysconfig/iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport - ...

  8. vs2008团队资源管理器安装步骤

    1.先装 VS2008TeamExplorer { NOTE: 要区分中英文版本Microsoft Visual Studio 2008 Service Pack 1 (iso) VS2008SP1C ...

  9. linux gd库不支持jpeg解决办法

    1. 查看gd库是否支持jpeg gd_info(); 2. 如果JPEG Support 不为1则不支持. 3.首先下载 libjpeg http://www.ijg.org/ ,进行安装 安装目录 ...

  10. [转]PHP中fopen,file_get_contents,curl的区别

    1.       fopen /file_get_contents 每次请求都会重新做DNS查询,并不对 DNS信息进行缓存.但是CURL会自动对DNS信息进行缓存.对同一域名下的网页或者图片的请求只 ...