丑陋敬请谅解:

求两列数的卷积:

递归版:

#include <stdio.h>
#include <algorithm>
#include <math.h>
using namespace std;
const double pi=acos(-);
int p[],q[];
struct complex
{
double x,y;
complex(double xx=,double yy=)
{
x=xx;
y=yy;
}
}a[],b[];
complex operator +(complex a,complex b){return complex(a.x+b.x,a.y+b.y);}
complex operator -(complex a,complex b){return complex(a.x-b.x,a.y-b.y);}
complex operator *(complex a,complex b){return complex(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);}
void DFT(int limit,complex *a)
{
if(limit==)
return;
int mid=limit>>;
complex a1[mid],a2[mid];
for(int i=;i<=limit;i+=)
{
a1[i>>]=a[i];
a2[i>>]=a[i+];
}
DFT(mid,a1);
DFT(mid,a2);
complex wn=complex(cos(2.0*pi/limit),sin(2.0*pi/limit));
complex w=complex(,);
for(int i=;i<mid;i++,w=w*wn)
{
a[i]=a1[i]+w*a2[i];
a[i+mid]=a1[i]-w*a2[i];
}
}
int pow(int x,int y)
{
if(y==)
return ;
int t=pow(x,y/);
if(y%==)
return t*t;
return t*t*x;
}
void IDFT(int limit,complex *a)
{
if(limit==)
return;
int mid=limit>>;
complex a1[mid],a2[mid];
for(int i=;i<=limit;i+=)
{
a1[i>>]=a[i];
a2[i>>]=a[i+];
}
IDFT(mid,a1);
IDFT(mid,a2);
complex wn=complex(cos(2.0*pi/limit),-sin(2.0*pi/limit));
complex w=complex(,);
for(int i=;i<mid;i++,w=w*wn)
{
a[i]=a1[i]+w*a2[i];
a[i+mid]=a1[i]-w*a2[i];
}
}
int main()
{
int k;
scanf("%d",&k);
int n=pow(,k);
for(int i=;i<=n-;i++)
scanf("%d",&p[i]);
for(int i=;i<=n-;i++)
scanf("%d",&q[i]);
for(int i=;i<=n-;i++)
a[i]=p[i];
for(int i=;i<=n-;i++)
b[i]=q[i];
int limit=*n;
DFT(limit,a);
DFT(limit,b);
for(int i=;i<=limit;i++)
a[i]=a[i]*b[i];
IDFT(limit,a);
for(int i=;i<=n-;i++)
printf("%d\n",(int)(a[i].x/limit+0.5));
printf("%d",(int)(a[n-].x/limit+0.5));
}

非递归版+蝶形算法优化:

#include<stdio.h>
#include <algorithm>
#include<math.h>
using namespace std;
const int MAXN=1e7+;
const double Pi=acos(-1.0);
int p[MAXN],q[MAXN];
struct complex
{
double x,y;
complex (double xx=,double yy=){x=xx,y=yy;}
}a[MAXN],b[MAXN];
complex operator + (complex a,complex b){ return complex(a.x+b.x , a.y+b.y);}
complex operator - (complex a,complex b){ return complex(a.x-b.x , a.y-b.y);}
complex operator * (complex a,complex b){ return complex(a.x*b.x-a.y*b.y , a.x*b.y+a.y*b.x);}
int N,M;
int l,r[MAXN];
int limit=;
void DFT(complex *A)
{
for(int i=;i<limit;i++)
if(i<r[i]) swap(A[i],A[r[i]]);
for(int mid=;mid<limit;mid<<=)
{
complex Wn( cos(Pi/mid) , sin(Pi/mid) );
for(int R=mid<<,j=;j<limit;j+=R)
{
complex w(,);
for(int k=;k<mid;k++,w=w*Wn)
{
complex x=A[j+k],y=w*A[j+mid+k];
A[j+k]=x+y;
A[j+mid+k]=x-y;
}
}
}
}
void IDFT(complex *A)
{
for(int i=;i<limit;i++)
if(i<r[i]) swap(A[i],A[r[i]]);
for(int mid=;mid<limit;mid<<=)
{
complex Wn( cos(Pi/mid) , -1.0*sin(Pi/mid) );
for(int R=mid<<,j=;j<limit;j+=R)
{
complex w(,);
for(int k=;k<mid;k++,w=w*Wn)
{
complex x=A[j+k],y=w*A[j+mid+k];
A[j+k]=x+y;
A[j+mid+k]=x-y;
}
}
}
}
int main()
{
scanf("%d%d",&N,&M);
for(int i=;i<=N;i++) scanf("%d",&p[i]);
for(int i=;i<=M;i++) scanf("%d",&q[i]);
for(int i=;i<=N;i++) a[i]=p[i];
for(int i=;i<=M;i++) b[i]=q[i];
while(limit<=N+M) limit<<=,l++;
for(int i=;i<limit;i++)
r[i]= ( r[i>>]>> )| ( (i&)<<(l-) ) ;
DFT(a);
DFT(b);
for(int i=;i<=limit;i++) a[i]=a[i]*b[i];
IDFT(a);
for(int i=;i<=N+M;i++)
printf("%d ",(int)(a[i].x/limit+0.5));
return ;
}

FFT版高精度乘法:

#include<stdio.h>
#include <algorithm>
#include<math.h>
#include <string.h>
using namespace std;
const double Pi=acos(-1.0);
char s1[],s2[];
int sum[];
struct complex
{
double x,y;
complex (double xx=,double yy=){x=xx,y=yy;}
}a[],b[];
complex operator + (complex a,complex b){ return complex(a.x+b.x , a.y+b.y);}
complex operator - (complex a,complex b){ return complex(a.x-b.x , a.y-b.y);}
complex operator * (complex a,complex b){ return complex(a.x*b.x-a.y*b.y , a.x*b.y+a.y*b.x);}
int N,M,L;
int len=;
int l,r[];
int limit=;
void fft(complex *A,int limit,int type)
{
for(int i=;i<limit;i++)
if(i<r[i]) swap(A[i],A[r[i]]);
for(int mid=;mid<limit;mid<<=)
{
complex Wn( cos(Pi/mid) , type*sin(Pi/mid) );
for(int R=mid<<,j=;j<limit;j+=R)
{
complex w(,);
for(int k=;k<mid;k++,w=w*Wn)
{
complex x=A[j+k],y=w*A[j+mid+k];
A[j+k]=x+y;
A[j+mid+k]=x-y;
}
}
}
if(type==-)for(int i=;i<limit;i++)A[i].x/=limit;
}
int main()
{
int n;
scanf("%d",&n);
scanf("%s",s1);
scanf("%s",s2);
int len1=strlen(s1);
int len2=strlen(s2);
int lenx=len1+len2;
for(len=;len<lenx;len<<=)
L++;
for(int i=;i<len;i++)
r[i]=((r[i>>])>>)|((i&)<<(L-));
for(int i=;i<len1;i++)
a[i]=complex(s1[len1-i-]-'',);
for(int i=len1;i<len;i++)
a[i]=complex(,);
for(int i=;i<len2;i++)
b[i]=complex(s2[len2-i-]-'',);
for(int i=len2;i<len;i++)
b[i]=complex(,);
fft(a,len,);fft(b,len,);
for(int i=;i<len;i++)
a[i]=a[i]*b[i];
fft(a,len,-);
for(int i=;i<len;i++)
sum[i]=int(a[i].x+0.5);
for(int i=;i<len;i++)
{
sum[i+]+=sum[i]/;
sum[i]%=;
}
len=len1+len2-;
while(sum[len]<= && len>)
len--;
for(int i=len;i>=;i--)
printf("%c",sum[i]+'');
return ;
}

FFT各种模板的更多相关文章

  1. FFT快速傅里叶模板

    FFT快速傅里叶模板…… /* use way: assign : h(x) = f(x) * g(x) f(x):len1 g(x):len2 1. len = 1; while(len < ...

  2. 多项式FFT相关模板

    自己码了一个模板...有点辛苦...常数十分大,小心使用 #include <iostream> #include <stdio.h> #include <math.h& ...

  3. 多项式FFT/NTT模板(含乘法/逆元/log/exp/求导/积分/快速幂)

    自己整理出来的模板 存在的问题: 1.多项式求逆常数过大(尤其是浮点数FFT) 2.log只支持f[0]=1的情况,exp只支持f[0]=0的情况 有待进一步修改和完善 FFT: #include&l ...

  4. hdu 1402 FFT(模板)

    A * B Problem Plus Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  5. FFT/NTT模板 既 HDU1402 A * B Problem Plus

    @(学习笔记)[FFT, NTT] Problem Description Calculate A * B. Input Each line will contain two integers A a ...

  6. FFT NTT 模板

    NTT: #include<cstdio> #include<cstring> #include<algorithm> using namespace std; # ...

  7. 多项式乘法(FFT)模板 && 快速数论变换(NTT)

    具体步骤: 1.补0:在两个多项式最前面补0,得到两个 $2n$ 次多项式,设系数向量分别为 $v_1$ 和 $v_2$. 2.求值:用FFT计算 $f_1 = DFT(v_1)$ 和 $f_2=DF ...

  8. 分治FFT/NTT 模板

    题目要我们求$f[i]=\sum\limits_{j=1}^{i}f[i-j]g[j]\;mod\;998244353$ 直接上$NTT$肯定是不行的,我们不能利用尚未求得的项卷积 所以要用$CDQ$ ...

  9. UOJ#34 FFT模板题

    写完上一道题才意识到自己没有在博客里丢过FFT的模板-- 这道题就是裸的多项式乘法,可以FFT,可以NTT,也可以用Karasuba(好像有人这么写没有T),也可以各种其他分治乘法乱搞-- 所以我就直 ...

随机推荐

  1. 6、mysql事务

    1.mysql事务 —mysql中,事务其实是一个最小的不可分割的工作单元.事务能够保证一个业务的完整性,例如:银行存款: a  - >    -100 >update user set ...

  2. Day9 - I - 不要62 HDU - 2089

    杭州人称那些傻乎乎粘嗒嗒的人为62(音:laoer).杭州交通管理局经常会扩充一些的士车牌照,新近出来一个好消息,以后上牌照,不再含有不吉利的数字了,这样一来,就可以消除个别的士司机和乘客的心理障碍, ...

  3. @vue-cli的安装及vue项目创建

    1.安装 Node.js & Vue CLI @vue/cli3,是vue-进行搭建的脚手架项目,它本质上是一个全局安装的 npm 包,通过安装它,可以为终端提供 vue 命令,进行vue项目 ...

  4. 防止SQL注入的登录页面

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/T ...

  5. 【QSBOJ】组成三位数

    题目描述 将1,2,…,9共9个数分成三组,分别组成三个三位数,且使这三个三位数构成1:2:3的比例,试求出所有满足条件的三个三位数. 例如:三个三位数192,384,576满足以上条件. 输出 输出 ...

  6. 第一单元总结:基于基础语言、继承和接口的简单OOP

    前情提要 到目前为止,OO课程已经完成了前三次的作业,分别为: 第一次作业:简单多项式的构造和求导.[正则表达式][数据结构][排序] 第二次作业:含三角函数因子的复杂多项式的构造.求导和化简.[递归 ...

  7. spring切面编程

    xml配置实现 先写三个类 public String amethod(String s) {  System.out.println("This is AAAAAAAAAAAAAAAA&q ...

  8. redis学习记录1 特性与优点

    1.存储结构:字符串.散列.列表.集合.有序集合. redis存储结构的优势:数据在redis中的储存方式和其在程序中的储存方式相近:redis对不同数据类型提供非常方便的操作方式,如使用集合类型储存 ...

  9. Express 应用程序生成器

    通过应用生成器工具 express-generator 可以快速创建一个应用的骨架. express-generator 包含了 express 命令行工具.通过如下命令即可安装: $ npm ins ...

  10. php截取指定两个字符之间的字符串

    //截取指定两个字符之间的字符串 public function cut($begin,$end,$str){ $b = mb_strpos($str,$begin) + mb_strlen($beg ...