概述
讲解:https://blog.csdn.net/qq_37136305/article/details/81184873 有点小问题,一个是代码不太对,另一个是倍增的图不太对
讲解+代码:https://www.cnblogs.com/zwfymqz/p/8244902.html
#include "bits/stdc++.h"
using namespace std;
const int MAXN = 1e7 + 10;
const double Pi = acos(-1.0);
struct Complex
{
double x, y;
Complex(double xx = 0, double yy = 0)
{ 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 l, r[MAXN], N, M;
int limit = 1;
void fft(Complex *A, int type)
{
for (int i = 0; i < limit; i++)
if (i < r[i])
{ swap(A[i], A[r[i]]); } //求出要迭代的序列
for (int mid = 1; mid < limit; mid <<= 1)
{
Complex Wn(cos(Pi / mid), type * sin(Pi / mid)); //单位根
for (int R = mid << 1, j = 0; j < limit; j += R)
{ //R是区间的长度,j表示前已经到哪个位置了
Complex w(1, 0); //幂
for (int k = 0; 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()
{
cin >> N >> M;
for (int i = 0; i <= N; i++) cin >> a[i].x;
for (int i = 0; i <= M; i++) cin >> b[i].x;
while (limit <= N + M)//补足位数 必须是2^x次方长度
{ limit <<= 1, l++; }
for (int i = 0; i < limit; i++)//翻转二进制下标 为倍增迭代做准备
r[i] = (r[i >> 1] >> 1) | ((i & 1) << (l - 1));
//两次fft 系数表示-》点值表示
fft(a, 1);
fft(b, 1);
for (int i = 0; i <= limit; i++) a[i] = a[i] * b[i];
fft(a, -1);//逆变换 点值表示-》系数表示
for (int i = 0; i <= N + M; i++)
printf("%d ", (int) (a[i].x / limit + 0.5));
return 0;
}
最后
以上就是英俊悟空为你收集整理的fft模板+讲解的全部内容,希望文章能够帮你解决fft模板+讲解所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复