[HDU 1402]A * B Problem Plus(FFT)
2015-03-13 21:51
246 查看
题目链接
http://acm.hdu.edu.cn/showproblem.php?pid=1402题目大意
高精度乘法,两个乘数的长度均<=50000<=50000思路
高精度乘法的过程和多项式乘法具有惊人的相似性,同样的,高精度乘法的暴力做法和暴力的多项式乘法一样,也是O(n2)O(n^2)观察到暴力的高精度乘法为了优化,可以在做完双重循环之后再一并取模,因此我们可以优化前面的双重循环过程,最后再进行取模。前面的双重循环过程,和暴力多项式乘法基本上是一样的,因此我们可以用FFT将高精度乘法优化到O(nlogn)O(nlogn)。将两个数字a、ba、b均看成是最高次为len(a)−1,len(b)−1len(a)-1,len(b)-1的两个多项式,然后在多项式中的xix^i前面的系数就是这个数的第i+1i+1位上的数字。
可以算是FFT模板水题吧。
代码
#include <iostream> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <algorithm> #include <complex> #include <cmath> #define MAXN 201000 #define PI 3.1415926535897384626 using namespace std; typedef complex<double> Complex; void reverse(Complex a[],int n) //对长度为n的复数序列a进行区间反转 { for(int i=1,j=n/2,k;i<n-1;i++) //!!!!! { if(i<j) swap(a[i],a[j]); k=n/2; while(j>=k) { j-=k; k>>=1; } if(j<k) j+=k; } } void FFT(Complex a[],int n,int flag) //对长为n的复数序列a做FFT,flag=1是求值,flag=-1是插值 { reverse(a,n); for(int i=1;i<n;i<<=1) { Complex wn=Complex(cos(PI/i),flag*sin(PI/i)); for(int j=0;j<n;j+=(i<<1)) { Complex w=Complex(1,0); for(int k=0;k<i;k++,w=w*wn) //!!!!! { Complex x=a[j+k],y=w*a[j+k+i]; a[j+k]=x+y; a[j+k+i]=x-y; } } } if(flag==-1) //这是插值操作,还要乘上1/n的系数 for(int i=0;i<n;i++) a[i]=Complex(a[i].real()/n,a[i].imag()); } char stra[MAXN],strb[MAXN]; int lena,lenb; Complex a[MAXN],b[MAXN]; int c[MAXN]; //最终的答案 int main() { while(scanf("%s%s",stra,strb)!=EOF) { memset(a,0,sizeof(a)); memset(b,0,sizeof(b)); lena=strlen(stra); lenb=strlen(strb); int len=lena+lenb+1; int N=1,k=0; //min(2^k)=min(N)>=lena+lenb+1 for(;N<len;N<<=1,k++); for(int i=0;i<lena;i++) a[i]=Complex((int)stra[lena-1-i]-'0',0); for(int i=0;i<lenb;i++) b[i]=Complex((int)strb[lenb-1-i]-'0',0); FFT(a,N,1); FFT(b,N,1); for(int i=0;i<N;i++) a[i]=a[i]*b[i]; FFT(a,N,-1); for(int i=0;i<N;i++) c[i]=(int)(a[i].real()+0.5); for(int i=0;i<N;i++) { c[i+1]+=c[i]/10; c[i]%=10; } N=lena+lenb-1; while(!c &&N>0) N--; for(int i=N;i>=0;i--) printf("%d",c[i]); printf("\n"); } return 0; }
相关文章推荐
- HDU 1402 A * B Problem Plus (FFT求高精度乘法)
- HDU 1402 A * B Problem Plus(FFT)
- HDU 1402 A * B Problem Plus (FFT求高精度乘法)
- HDU 1402 A * B Problem Plus (FFT求高精度乘法)
- [HDU 1402] A * B Problem Plus (FFT入门)
- HDU 1402 A * B Problem Plus(FFT模版题)
- HDU 1402 A * B Problem Plus(FFT)
- HDU 1402 A * B Problem Plus (FFT求高精度乘法)
- FFT(快速傅立叶变换):HDU 1402 A * B Problem Plus
- 【HDU 1402】A * B Problem Plus(FFT)
- hdu 1402 A * B Problem Plus FFT模板
- HDU 1402 A * B Problem Plus (FFT求高精度乘法)
- HDU 1402 A * B Problem Plus (FFT求高精度乘法)
- hdu----(1402)A * B Problem Plus(FFT模板)
- HDU 1402 A * B Problem Plus FFT
- HDU1402 A * B Problem Plus(FFT)
- hdu1402 A * B Problem Plus (FFT)
- HDU 1402 A * B Problem Plus (FFT求高精度乘法)
- HDU 1402 A * B Problem Plus(FFT加速优化乘法)
- HDU 1402 A * B Problem Plus FFT入门题