【BZOJ-2179】FFT快速傅里叶 FFT

2179: FFT快速傅立叶

Time Limit: 10 Sec  Memory Limit: 259 MB
Submit: 2978  Solved: 1523
[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

12

数据范围:
n<=60000

HINT

Source

Solution

RT..留个板子

Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
struct Complex{
	double r,i;
	Complex (double R=0.0,double I=0.0) {r=R,i=I;}
	Complex operator + (Complex & A) const {return Complex(r+A.r,i+A.i);}
	Complex operator - (Complex & A) const {return Complex(r-A.r,i-A.i);}
	Complex operator * (Complex & A) const {return Complex(r*A.r-i*A.i,r*A.i+i*A.r);}
};
#define MAXN 600010
#define Pai acos(-1.0)
Complex A[MAXN],B[MAXN];
int len,N,ans[MAXN];
char s[MAXN];
inline void Prework()
{
	len=1;
	while (len < (N<<1)) len<<=1;  //扩展到2的幂次
	for (int i=N; i<len; i++) A[i]=Complex(0,0),B[i]=Complex(0,0); //补零
}
inline void Rader(Complex *x)
{
	for (int i=1,j=len>>1,k; i<len-1; i++)
		{
			if (i<j) swap(x[i],x[j]);
			k=len>>1;
			while (j>=k) j-=k,k>>=1;
			if (j<k) j+=k;
		}
}//位逆序置换
inline void DFT(Complex *x,int opt)
{
	Rader(x);
	for (int h=2; h<=len; h<<=1) //操作的长度,h=1不用管
		{
			Complex Wn( cos(opt*2*Pai/h) , sin(opt*2*Pai/h) );
			for (int i=0; i<len; i+=h)
				{
					Complex W(1,0);
					for (int j=i; j<i+h/2; j++)
						{
							Complex u=x[j],t=W*x[j+h/2];
							x[j]=u+t,x[j+h/2]=u-t; //蝴蝶操作
							W=W*Wn;
						}
				}
		}
	if (opt==-1) //插值时要/len
		for (int i=0; i<len; i++)
			x[i].r/=len;
}//opt=1 DFT opt=-1 IDFT
inline void FFT(Complex *A,Complex *B)
{
	DFT(A,1); DFT(B,1);
	for (int i=0; i<len; i++)
		A[i]=A[i]*B[i]; //点值乘
	DFT(A,-1);
}
int main()
{
	scanf("%d",&N);
	scanf("%s",s+1);
	for (int i=N,l=-1; i>=1; i--) A[++l].r=s[i]-‘0‘;
	scanf("%s",s+1);
	for (int i=N,l=-1; i>=1; i--) B[++l].r=s[i]-‘0‘;
	Prework();
	FFT(A,B);

	for (int i=0; i<len; i++) ans[i]=(int)(A[i].r+0.5);
	for (int i=0; i<len; i++) ans[i+1]+=ans[i]/10,ans[i]%=10;
	while (--len && !ans[len]);
	//高精乘的进位和去0

	for (int i=len; i>=0; i--) putchar(ans[i]+‘0‘);
	puts("");
	return 0;
}

  

时间: 2024-10-08 19:35:10

【BZOJ-2179】FFT快速傅里叶 FFT的相关文章

【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

【BZOJ】【2179】FFT快速傅里叶

FFT 做的第二道用到FFT的……好吧其实还是模板题-_-b 百度上说好像分治也能做……不过像FFT这种敲模板的还是省事=.= 1 /************************************************************** 2 Problem: 2179 3 User: Tunix 4 Language: C++ 5 Result: Accepted 6 Time:1236 ms 7 Memory:9184 kb 8 *********************

FFT快速傅里叶模板

FFT快速傅里叶模板-- /* use way: assign : h(x) = f(x) * g(x) f(x):len1 g(x):len2 1. len = 1; while(len < 2 * len1 || len < 2 * len2) len <<= 1; 2. for i=0 to len1-1 : x1[i](f(i),0) for i=len1 to len-1 : x1[i](0.0) g(x) is same..... 3. fft(x1,len,1) ff

P1919 【模板】A*B Problem升级版(FFT快速傅里叶)

P1919 [模板]A*B Problem升级版(FFT快速傅里叶) 思路还是挺简单的. 输入的2个数 \(a=\overline{a_n a_{n-1} a_{n-2}\cdots a_{0}}\) , \(b=\overline{b_m b_{m-1} b_{m-2}\cdots b_{0}}\) 直接把 \(a_i\) 和 \(b_i\) 看做多项式 A 和 B 的系数,做多项式乘法即可.因为 a ,b 可以看做以 \(a_i,b_i\) 为系数,自变量为10的多项式的值,乘完后的多项式的

傅里叶变换,fft,fft energy

傅里叶变换:将信号转化到频率空间,详解:http://blog.jobbole.com/70549/ 图像傅里叶变换:傅立叶变换的物理意义是将图像的灰度分布函数变换为图像的频率分布函数, 空间三维,图像二维,因此空间中物体在另一个维度上的关系,就必须由梯度来表示,这样我们才能通过观察图像得知物体在三维空间中的对应关系. 图像傅里叶详解:http://www.cnblogs.com/EverYoung/archive/2012/05/29/2524058.html fft:快速傅里叶变换,nump

bzoj 2179: FFT快速傅立叶 -- FFT

2179: FFT快速傅立叶 Time Limit: 10 Sec  Memory Limit: 259 MB Description 给出两个n位10进制整数x和y,你需要计算x*y. Input 第一行一个正整数n. 第二行描述一个位数为n的正整数x. 第三行描述一个位数为n的正整数y. Output 输出一行,即x*y的结果. Sample Input 1 3 4 Sample Output 12 数据范围: n<=60000 HINT #include<map> #include

BZOJ 2179: FFT快速傅立叶

2179: FFT快速傅立叶 Time Limit: 10 Sec  Memory Limit: 259 MBSubmit: 3138  Solved: 1620[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 Outpu

BZOJ 2179 FFT快速傅立叶 ——FFT

[题目分析] 快速傅里叶变换用于高精度乘法. 其实本质就是循环卷积的计算,也就是多项式的乘法. 两次蝴蝶变换. 二进制取反化递归为迭代. 单位根的巧妙取值,是的复杂度成为了nlogn 范德蒙矩阵计算逆矩阵又减轻了拉格朗日插值法的复杂度. 十分神奇. [代码] #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <set> #includ

BZOJ 2179 FFT快速傅立叶 快速傅里叶变换

题目大意:给定两个高精度整数,求两个数的乘积 FFT大法好 系统的complex比手写慢了2.5倍 简直吓死人- - #include <cmath> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 131080 #define PI 3.1415926535897932384626433832795028841971