HDU 1402 A * B Problem Plus(FFT)
2016-03-04 09:42
375 查看
Description
给出两个数A和B,求A*B
Input
多组用例,每组用例为两个数字串分别表示A和B,串长不超过50000
Output
输出A*B
Sample Input
1
2
1000
2
Sample Output
2
2000
Solution
直接高精度模拟乘法过程会爆,考虑到如果将一个数字串看做一个序列,那么乘法过程就相当于是两个序列的离散卷积,用FFT可以将乘法过程的复杂度从O(n^2)降到O(nlogn)
Code
给出两个数A和B,求A*B
Input
多组用例,每组用例为两个数字串分别表示A和B,串长不超过50000
Output
输出A*B
Sample Input
1
2
1000
2
Sample Output
2
2000
Solution
直接高精度模拟乘法过程会爆,考虑到如果将一个数字串看做一个序列,那么乘法过程就相当于是两个序列的离散卷积,用FFT可以将乘法过程的复杂度从O(n^2)降到O(nlogn)
Code
#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #include<cmath> using namespace std; #define maxn 111111 typedef long long ll; #define PI acos(-1.0) struct complex { double r,i; complex(double _r=0,double _i=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); } }; void change(complex *x,int len) { for(int i=1,j=len/2;i<len-1;i++) { if(i<j)swap(x[i],x[j]); int k=len/2; while(j>=k) { j-=k; k/=2; } if(j<k)j+=k; } } void fft(complex *x,int len,int sta) { change(x,len); for(int m=2;m<=len;m<<=1) { complex Wn(cos(-sta*2*PI/m),sin(-sta*2*PI/m)); for(int i=0;i<len;i+=m) { complex W(1,0); for(int j=i;j<i+m/2;j++) { complex x1=x[j],x2=W*x[j+m/2]; x[j]=x1+x2,x[j+m/2]=x1-x2; W=W*Wn; } } } if(sta==-1) for(int i=0;i<len;i++) x[i].r/=len; } char s1[maxn],s2[maxn]; complex a[2*maxn],b[2*maxn]; int ans[2*maxn]; int main() { while(~scanf("%s%s",s1,s2)) { int len1=strlen(s1),len2=strlen(s2),len=1; while(len<len1*2||len<len2*2)len<<=1; for(int i=0;i<len1;i++)a[i]=complex(s1[len1-i-1]-'0',0); for(int i=len1;i<len;i++)a[i]=complex(0,0); for(int i=0;i<len2;i++)b[i]=complex(s2[len2-i-1]-'0',0); for(int i=len2;i<len;i++)b[i]=complex(0,0); fft(a,len,1);fft(b,len,1); for(int i=0;i<len;i++)a[i]=a[i]*b[i]; fft(a,len,-1); 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; } len=len1+len2-1; while(ans[len]<=0&&len>0)len--; for(int i=len;i>=0;i--)printf("%c",ans[i]+'0'); printf("\n"); } return 0; }
相关文章推荐
- 如何安全退出已调用多个Activity的Application?
- 第三章 文件IO复习
- Json 讲解
- Windows下虚拟机安装Ubuntu15.10 Destop简易操作过程
- Ubuntu Remmina 远程桌面提示 “无法连接到RDP服务器”
- AQS源码分析(超时、中断与其他)
- zend framework中使用memcache的方法
- web.xml文件的作用
- 多线程--信号量
- textWriter = new XmlTextWriter(xmlWriter);
- 卖萌、卖萌,还是卖萌,VR游戏的突破口就在这里
- JavaBean
- windows phone 8.1 让项目开启蓝牙genericAttributeProfile
- 生活在继续,梦,也要继续
- AQS源码分析(共享与互斥)
- VI编辑器的配置
- java中dynamic web project与web project 的区别
- 2015年大二上-数据结构-查找-1-(3)-二叉排序树
- 1010. Radix (25)
- linux虚拟机,安装samba,共享文件夹