UOJ #34 多项式乘法 FFT快速傅立叶变换

题目大意:这是一道模板题。

CODE:

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX 1000010
using namespace std;
const double PI = acos(-1.0);

struct Complex{
	double x,y;

	Complex(double _,double __ = .0):x(_),y(__) {}
	Complex() {}
	void operator +=(const Complex &a) {
		x += a.x,y += a.y;
	}
	void operator -=(const Complex &a) {
		x -= a.x,y -= a.y;
	}
	void operator /=(double a) {
		x /= a,y /= a;
	}
	void operator *=(const Complex &a) {
		double _ = x * a.x - y * a.y,__ = x * a.y + y * a.x;
		x = _,y = __;
	}
	Complex operator +(const Complex &a)const {
		return Complex(x + a.x,y + a.y);
	}
	Complex operator -(const Complex &a)const {
		return Complex(x - a.x,y - a.y);
	}
	Complex operator /(double a)const {
		return Complex(x / a,y / a);
	}
	Complex operator *(const Complex &a)const {
		return Complex(x * a.x - y * a.y,x * a.y + y * a.x);
	}
};

inline void FFT(Complex A[],int cnt,int flag)
{
	for(int i = 0,k = 0; i < cnt; ++i) {
		if(i < k)	swap(A[i],A[k]);
		for(int j = cnt >> 1; (k ^= j) < j; j >>= 1);
	}
	int i,j;
	Complex w,wn,t;
	for(int k = 2; k <= cnt; k <<= 1)
		for(wn = Complex(cos(2 * PI / k),flag * sin(2 * PI / k)),i = 0; i < cnt; i += k)
			for(w = 1.0,j = 0; j < k >> 1; ++j,w *= wn) {
				t = w * A[i + j + (k >> 1)];
				A[i + j + (k >> 1)] = A[i + j] - t;
				A[i + j] += t;
			}
	if(!~flag)
		for(int i = 0; i < cnt; ++i)
			A[i] /= cnt;
}

int l1,l2;
Complex A[MAX],B[MAX];

int main()
{
	cin >> l1 >> l2;
	for(int i = 0; i <= l1; ++i)	scanf("%lf",&A[i].x);
	for(int i = 0; i <= l2; ++i)	scanf("%lf",&B[i].x);
	int l = l1 + l2,cnt;
	for(cnt = 1; cnt <= l; cnt <<= 1);
	FFT(A,cnt,1),FFT(B,cnt,1);
	for(int i = 0; i < cnt; ++i)
		A[i] *= B[i];
	FFT(A,cnt,-1);
	for(int i = 0; i <= l1 + l2; ++i)
		printf("%d%c",int(A[i].x + .5)," \n"[i == l1 + l2]);
	return 0;
}
时间: 2024-12-11 08:30:17

UOJ #34 多项式乘法 FFT快速傅立叶变换的相关文章

UOJ #34 多项式乘法

题目链接:多项式乘法 保存一发FFT与NTT板子. 学习链接:从多项式乘法到快速傅里叶变换 FFT NTT 注意差值回来的时候不取反也是可以的,只不过需要把数组\(reverse\)一下(根据单位复数根的性质应该不难理解) 代码(FFT): #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<co

●UOJ 34 多项式乘法

题链: http://uoj.ac/problem/34 题解: FFT入门题. (终于接触到迷一样的FFT了) 初学者在对复数和单位根有简单了解的基础上,可以直接看<再探快速傅里叶变换>(毛啸). (主要用于求两个序列的卷积) 代码: 递归版: #include<bits/stdc++.h> #define MAXN 300000 using namespace std; const double Pi=acos(-1); struct Z{ double real,image;

FFT快速傅立叶变换的工作原理

实数DFT,复数DFT,FFT FFT是计算DFT的快速算法,但是它是基于复数的,所以计算实数DFT的时候需要将其转换为复数的格式,下图展示了实数DFT和虚数DFT的情况,实数DFT将时域中N点信号转换成2个(N/2+1)点的频域信号,其中1个(N/2+1)点的信号称之为实部,另一个(N/2+1)点的信号称之为虚部,实部和虚部分别是正弦和余弦信号的幅度. 相比较而言,复数DFT将2个N点的时域信号转换为2个N点的频域信号.时域和频域中,1个N点信号是实部,另1个N点信号是虚部. 如果要计算N点实

FFT(快速傅立叶变换):HDU 1402 A * B Problem Plus

Calculate A * B. Input Each line will contain two integers A and B. Process to end of file. Note: the length of each integer will not exceed 50000. Output For each case, output A * B in one line. Sample Input 1 2 1000 2 Sample Output 2 2000 唉,模板题,膜的邝

spoj VFMUL FFT快速傅立叶变换模板题

题意:求两个数相乘. 第一次写非递归的fft,因为一个数组开小了调了两天TAT. #include<iostream> #include<cstring> #include<algorithm> #include<cstdio> #include<cmath> using namespace std; #define PI 3.1415926535897932384 #define MAXN 1200000 #pragma optimize(&q

快速傅立叶变换算法FFT——图像处理中的数学原理详解22

欢迎关注我的博客专栏"图像处理中的数学原理详解" 全文目录请见 图像处理中的数学原理详解(总纲) http://blog.csdn.net/baimafujinji/article/details/48467225 图像处理中的数学原理详解(已发布的部分链接整理) http://blog.csdn.net/baimafujinji/article/details/48751037 交流学习可加图像处理研究学习QQ群(529549320) 傅立叶变换以高等数学(微积分)中的傅立叶级数为基

一步一步的无障碍理解快速傅立叶变换

/////////////////////////////////////////////////////////////////////////////////////////////////////// 作者:tt2767 声明:本文遵循以下协议自由转载-非商用-非衍生-保持署名|Creative Commons BY-NC-ND 3.0 查看本文更新与讨论请点击:http://blog.csdn.net/tt2767 链接被删请百度: CSDN tt2767 ///////////////

快速傅立叶变换

多项式 对于多项式$ f\left(x\right)=\sum_{i=0}^{|f|}{f_ix^i} $,其中|f|表示多项式的阶数,fi表示多项式f中x^i的系数. 多项式的加法定义为$ c\left(x\right)=a\left(x\right)+b\left(x\right)=\sum_{i=0}^{\max\left(|a|,|b|\right)}{\left(a_i+b_i\right)x^i} $,即$ c_k=a_k+b_k $. 多项式的乘法定义为$ c\left(x\rig

【BZOJ 2179】【FFT模板】 FFT快速傅立叶

2179: FFT快速傅立叶 Time Limit: 10 Sec Memory Limit: 259 MB Submit: 1595 Solved: 792 [Submit][Status][Discuss] Description 给出两个n位10进制整数x和y,你需要计算x*y. Input 第一行一个正整数n. 第二行描述一个位数为n的正整数x. 第三行描述一个位数为n的正整数y. Output 输出一行,即x*y的结果. Sample Input 1 3 4 Sample Output