FFT各种模板
丑陋敬请谅解:
求两列数的卷积:
递归版:
#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各种模板的更多相关文章
- FFT快速傅里叶模板
FFT快速傅里叶模板…… /* use way: assign : h(x) = f(x) * g(x) f(x):len1 g(x):len2 1. len = 1; while(len < ...
- 多项式FFT相关模板
自己码了一个模板...有点辛苦...常数十分大,小心使用 #include <iostream> #include <stdio.h> #include <math.h& ...
- 多项式FFT/NTT模板(含乘法/逆元/log/exp/求导/积分/快速幂)
自己整理出来的模板 存在的问题: 1.多项式求逆常数过大(尤其是浮点数FFT) 2.log只支持f[0]=1的情况,exp只支持f[0]=0的情况 有待进一步修改和完善 FFT: #include&l ...
- hdu 1402 FFT(模板)
A * B Problem Plus Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Other ...
- FFT/NTT模板 既 HDU1402 A * B Problem Plus
@(学习笔记)[FFT, NTT] Problem Description Calculate A * B. Input Each line will contain two integers A a ...
- FFT NTT 模板
NTT: #include<cstdio> #include<cstring> #include<algorithm> using namespace std; # ...
- 多项式乘法(FFT)模板 && 快速数论变换(NTT)
具体步骤: 1.补0:在两个多项式最前面补0,得到两个 $2n$ 次多项式,设系数向量分别为 $v_1$ 和 $v_2$. 2.求值:用FFT计算 $f_1 = DFT(v_1)$ 和 $f_2=DF ...
- 分治FFT/NTT 模板
题目要我们求$f[i]=\sum\limits_{j=1}^{i}f[i-j]g[j]\;mod\;998244353$ 直接上$NTT$肯定是不行的,我们不能利用尚未求得的项卷积 所以要用$CDQ$ ...
- UOJ#34 FFT模板题
写完上一道题才意识到自己没有在博客里丢过FFT的模板-- 这道题就是裸的多项式乘法,可以FFT,可以NTT,也可以用Karasuba(好像有人这么写没有T),也可以各种其他分治乘法乱搞-- 所以我就直 ...
随机推荐
- HDU 5525:Product 欧拉定理
Product Accepts: 21 Submissions: 171 Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072 ...
- 小程序的tabar顶部和底部导航的区别
最近有人说小程序的底部tabar放在顶部会出现问题,那么先看看如何放在顶部吧:图片效果: 这里呢,在官方文档是有说明,tabbar 的属性设置里面有个position属性,position只支持bot ...
- IOS 常用功能代码
1. 关闭/隐藏键盘 resignFirstResponder 响应view的方法 -(IBAction)fname:(id)sender{ [sender resignFirstResponder] ...
- 三 Road
3—5年程序员的发展和出路在哪里? 是继续做技术人,还是向管理者发力?是继续留在大公司,还是转投潜力小公司?如果没有核心竞争力,入行一两年的新程序员朋友是可以替代你大部分工作的,而且薪资还低,要怎么办 ...
- 获取QQ群中的所有群友QQ
package com.jm.mail.tools; import java.io.BufferedReader; import java.io.IOException; import java.io ...
- 深入了解memcached
一.memcached如何支持高并发 Memcached使用多路复用 I/O模型(如epoll.select等).传统阻塞 I/O中,系统可能会因为某个用户连接还没做好 I/O准备而一直等待,直到这个 ...
- idea跑mapreduce结果为空白文本,idea代码被莫名其妙地改动了
遇到如题的错误, 一开始查找Step1Main.java的代码错误,尝试关掉分区设置,还是一样. 后来以为是mapper或reducer不执行,网上查找了半天也没有正确原因. 最终,偶然间看到redu ...
- Saul's Blog
2019Falg完成情况 - 脱贫脱单不脱发(已完成) - 买辆帕拉梅拉 (已完成) - 不再是个蒟蒻(已完成) - 来一场说走就走的旅行(已完成) - 停止口嗨(未完成) ᑋᵉᑊᑊᵒ ᵕ̈ ₂₀₂₀ ...
- 058、Java中定义一个没有参数没有返回值的方法
01.代码如下: package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public ...
- 037、Java中利用判断语句实现三目运算的功能
01.代码如下: package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public ...