丑陋敬请谅解:

求两列数的卷积:

递归版:

#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. Python可视化界面编程入门

    Python可视化界面编程入门具体实现代码如所示: (1)普通可视化界面编程代码入门: import sysfrom PyQt5.QtWidgets import QWidget,QApplicati ...

  2. 【剑指Offer面试编程题】题目1386:旋转数组的最小数字--九度OJ

    题目描述: 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转.输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素.例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋转 ...

  3. 六、ibatis1.2.8查询性能优化,实现百万数据zip导出

    经测试发现将查询的结果100万数据(池子中共有大概14亿的数据)写入Excle文件并进行压缩导出zip文件最耗时的地方竟然在查询,因此本篇文章主要是针对如何在spring+ibatis1.2.8中优化 ...

  4. 使用IDEA,Eclispe搭建Spring Boot项目

    如何创建一个Spring Boot项目?这里使用maven来进行依赖管理,根据常用的IDE,可以使用IDEA.Eclipse.或者访问官方网站搭建. 项目搭建环境准备 JDK:1.8 MAVEN:3. ...

  5. Spring事务原理分析-部分二

    Spring事务原理分析-部分二 说明:这是我在蚂蚁课堂学习了余老师Spring手写框架的课程的一些笔记,部分代码代码会用到余老师的课件代码.这不是广告,是我听了之后觉得很好. 课堂链接:Spring ...

  6. [易语言][ExDui][Tutorial]0.Hello,world!

    原创博客,请勿在未经授权的情况下转载. At the Beginning... 由于近期爱好摸鱼,并且对Gui开发萌生一丝兴趣.在尝试WPF被虐,使用Qt却不太喜欢整套庞大的框架后-- I choos ...

  7. selenium+chrome抓取淘宝宝贝-崔庆才思路

    站点分析 源码及遇到的问题 在搜索时,会跳转到登录界面 step1:干起来! 先取cookie step2:载入cookie step3:放飞自我 关于phantomJS浏览器的问题 源码 站点分析 ...

  8. java与MySQL数据库的连接

    java与MySQL数据库的连接 1.数据库的安装和建立参见上一篇博客中的第1,2步骤.(http://blog.csdn.net/nuptboyzhb/article/details/8043091 ...

  9. mysql explain参数解析

    建表语句 -- ---------------------------- -- Records of departments -- ---------------------------- INSER ...

  10. 2-10 就业课(2.0)-oozie:5、通过oozie执行hive的任务

    4.2.使用oozie调度我们的hive 第一步:拷贝hive的案例模板 cd /export/servers/oozie-4.1.0-cdh5.14.0 cp -ra examples/apps/h ...