hdu1402A * B Problem Plus
2016-03-20 21:45
204 查看
链接:http://acm.hdu.edu.cn/showproblem.php?pid=1402
题意:计算A*B。
分析:由于A,B很大,长度可能达50000,所以一般的高精度乘法是不行的。所以要用FFT,这个叫快速傅里叶变换。算法导论第30章有讲,讲得挺清晰的,还有就是picks的博客也不错:http://picks.logdown.com/posts/177631-fast-fourier-transform。O(nlogn)
代码:
#include<map> #include<set> #include<cmath> #include<queue> #include<bitset> #include<math.h> #include<cstdio> #include<vector> #include<string> #include<cstring> #include<iostream> #include<algorithm> #pragma comment(linker, "/STACK:102400000,102400000") using namespace std; const int N=50010; const int MOD1=1000007; const int MOD2=100000009; const int MAX=1000000000; const double EPS=0.00000001; typedef long long ll; const ll MOD=1000000007; const ll INF=10000000010; const double pi=acos(-1.0); typedef double db; typedef unsigned long long ull; char s ,t ; struct Complex{ db r,i; Complex() {} Complex(db r,db i):r(r),i(i) {} Complex operator + (const Complex &t) const { return Complex(r+t.r,i+t.i); } Complex operator - (const Complex &t) const { return Complex(r-t.r,i-t.i); } Complex operator * (const Complex &t) const { return Complex(r*t.r-i*t.i,r*t.i+i*t.r); } }a[3*N],b[3*N]; void FFT(Complex x[],int n,int rev) { int i,j,k,t,ds; Complex w,u,wn; for (i=1;i<n;i++) { for (j=0,t=i,k=n>>1;k;k>>=1,t>>=1) j=j<<1|t&1; if (i<j) swap(x[i],x[j]); } for (i=2,ds=1;i<=n;ds=i,i<<=1) { w=Complex(1,0);wn=Complex(cos(rev*2*pi/i),sin(rev*2*pi/i)); for (j=0;j<ds;j++,w=w*wn) for (k=j;k<n;k+=i) { u=w*x[k+ds];x[k+ds]=x[k]-u;x[k]=x[k]+u; } } if (rev==-1) for (i=0;i<n;i++) x[i].r/=n; } int num[3*N]; void solve() { int i,k=0,n=1,les,let; les=strlen(s); let=strlen(t); while (n<les+let) n<<=1; for (i=0;i<les;i++) a[i]=Complex(s[les-i-1]-'0',0); for (i=les;i<n;i++) a[i]=Complex(0,0); for (i=0;i<let;i++) b[i]=Complex(t[let-i-1]-'0',0); for (i=let;i<n;i++) b[i]=Complex(0,0); FFT(a,n,1);FFT(b,n,1); for (i=0;i<n;i++) a[i]=a[i]*b[i]; FFT(a,n,-1); for (i=0;i<n;i++) { k+=(int)(a[i].r+0.1); num[i]=k%10;k/=10; } while (k) { num[n++]=k%10;k/=10; } while (n>1&&!num[n-1]) n--; for (i=n-1;i>=0;i--) printf("%d", num[i]); printf("\n"); } int main() { while (scanf("%s%s", s, t)!=EOF) solve(); return 0; }
相关文章推荐
- 英文歌曲:Yesterday Once More(昨日重现)
- 【机房个人重构】数据库设计之物理设计
- 汇编学习3
- SNAT
- webView的使用
- 欢迎使用CSDN-markdown编辑器
- Java - 多线程
- print(),print_r(),echo()的区别
- DOM对象编程练习小结
- Android系统组件BroadcastReceiver
- u插件开发,图解每个js之前的通信
- 整数因子分解
- 猎豹MFC--Socket编程基础TCP服务端和客户端
- 基于dos的多任务系统实现
- 读书笔记| (二)ARM9 嵌入式学习:代码 & 原理篇
- UML之用例图
- 回到顶部和回到底部动画
- 开发个人总结
- css 学习笔记二
- 发现群组(一)建立RSS数据集