hdu 1402 A * B Problem Plus(FFT-大整数乘法)
来源:互联网 发布:侠客风云传低配置优化 编辑:程序博客网 时间:2024/06/05 05:39
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
1210002
Sample Output
22000
Author
DOOM III
Recommend
DOOM III
题意简单明了:求两个大整数的乘积。
因为长度很长,所以不能用高精度直接模拟,会超时。
所以用FFT,FFT是用来解决两个多项式的卷积问题。而一个整数也可以看做是一个多项式,
一个整数A = a0*(10^0) + a1*(10^1) + (a2*10^2) + .... + a len-1 * (10^(len-1))
用FFT求出多项式的系数之后,再从地位到高位进位,最后再从后面一个不为0的位置往前面输出就行了。
#include <stdio.h>#include <string.h>#include <iostream>#include <algorithm>#include <math.h>using namespace std;const double PI = acos(-1.0);//复数结构体struct complex{ double r,i; complex(double _r = 0.0,double _i = 0.0) { r = _r; i = _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); } complex operator *(const complex &b) { return complex(r*b.r-i*b.i,r*b.i+i*b.r); }};/* * 进行FFT和IFFT前的反转变换。 * 位置i和 (i二进制反转后位置)互换 * len必须去2的幂 */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]); //交换互为小标反转的元素,i<j保证交换一次 //i做正常的+1,j左反转类型的+1,始终保持i和j是反转的 k = len/2; while(j >= k) { j -= k; k /= 2; } if(j < k) j += k; }}/* * 做FFT * len必须为2^k形式, * on==1时是DFT,on==-1时是IDFT */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;}const int MAXN = 200010;complex x1[MAXN],x2[MAXN];char str1[MAXN/2],str2[MAXN/2];int sum[MAXN];int main(void){ while(scanf("%s%s",str1,str2)==2) { int len1 = strlen(str1); int len2 = strlen(str2); int len = 1; while(len < len1*2 || len < len2*2) len<<=1; for(int i = 0;i < len1;i++) x1[i] = complex(str1[len1-1-i]-'0',0); for(int i = len1;i < len;i++) x1[i] = complex(0,0); for(int i = 0;i < len2;i++) x2[i] = complex(str2[len2-1-i]-'0',0); for(int i = len2;i < len;i++) x2[i] = complex(0,0); fft(x1,len,1); fft(x2,len,1); for(int i = 0;i < len;i++) x1[i] = x1[i]*x2[i]; fft(x1,len,-1); for(int i=0;i<len;i++) sum[i] = (int)(x1[i].r+0.5); len = len1 + len2 - 1; for(int i=0;i<len;i++) { sum[i+1] += sum[i]/10; sum[i] %= 10; } while(sum[len] <= 0 && len > 0) len--; for(int i=len;i>=0;i--) printf("%d",sum[i]); printf("\n"); } return 0;}
阅读全文
0 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求高精度乘法)
- 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
- hdu 1402 A * B Problem Plus[【FFT】
- HDU 1402 A * B Problem Plus FFT
- 关于Android沉浸式状态栏的解决方法之一(伪沉浸式)
- 使用git pull文件时和本地文件冲突怎么办?
- Android之linux基础教学之六 异常
- Kotlin Reference (九) Properties and Fields
- 把idea的项目上传的gitlab上
- hdu 1402 A * B Problem Plus(FFT-大整数乘法)
- Android之linux基础教学之七 中断下半部之软中断
- HDU 6073 Matching In Multiplication(机智)
- 大话数据结构 code 第七章 05最小生成树_Prim
- C++中的STL中map用法详解
- Http协议详解
- 面包会有的,牛奶也会有的
- Android之linux基础教学之八 内核同步介绍
- Xftp向服务器上传文件操作