A * B Problem Plus
Problem Description
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.
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
FFT的模板题。我们把数字的每一位看成i*(x^j),当我们把x取成10的时候我们就得到了这个大整数
#include <bits/stdc++.h> using namespace std; const int maxn = 50000+500; const double pi = acos(-1.0); const double PI = acos(-1.0); #define fft FFT #define r real struct Complex { double r,i; Complex(double _r,double _i):r(_r),i(_i){} Complex(){} Complex operator +(const Complex &b) { return Complex(r+b.r,i+b.i); } Complex operator -(const Complex &b) { return Complex(r-b.r,i-b.i); } Complex operator *(const Complex &b) { return Complex(r*b.r-i*b.i,r*b.i+i*b.r); } }; void change(Complex y[],int len) { int i,j,k; for(i = 1, j = len/2;i < len-1;i++) { if(i < j)swap(y[i],y[j]); k = len/2; while( j >= k) { j -= k; k /= 2; } if(j < k)j += k; } } void fft(Complex y[],int len,int on) { change(y,len); for(int h = 2;h <= len;h <<= 1) { Complex wn(cos(-on*2*pi/h),sin(-on*2*pi/h)); for(int j = 0;j < len;j += h) { Complex w(1,0); for(int k = j;k < j+h/2;k++) { Complex u = y[k]; Complex t = w*y[k+h/2]; y[k] = u+t; y[k+h/2] = u-t; w = w*wn; } } } if(on == -1) for(int i = 0;i < len;i++) y[i].r /= len; } char numA[maxn],numB[maxn]; Complex a[maxn*2],b[maxn*2]; int ans[maxn*2]; int main() { //freopen("de.txt","r",stdin); while (~scanf("%s",numA)){ int lenA = strlen(numA); int sa = 0; while ((1<<sa)<lenA) sa++; scanf("%s",numB); int lenB = strlen(numB); int sb = 0; while ((1<<sb)<lenB) sb++; int len = (1<<(max(sa,sb)+1)); for (int i=0;i<len;++i){ if (i<lenA) a[i] = Complex(numA[lenA-i-1]-'0',0); else a[i] = Complex(0,0); if (i<lenB) b[i] = Complex(numB[lenB-i-1]-'0',0); else b[i] = Complex(0,0); } fft(a,len,1); fft(b,len,1);//将a b 换成点值表达 for (int i=0;i<len;++i) a[i] = a[i]*b[i];//点值相乘 fft(a,len,-1);//DFT逆变换回去 for (int i=0;i<len;++i) ans[i] = (int)(a[i].r+0.5);//误差处理 for (int i=0;i<len-1;++i){ ans[i+1]+=ans[i]/10;//处理进位问题 ans[i]%=10; } bool flag = 0;//调整输出格式处理前导零问题 for (int i=len-1;i>=0;--i){ if (ans[i]) printf("%d",ans[i]),flag=1; else if (flag||i==0) printf("0"); } printf(" "); } return 0; }