FFT(快速傅立叶变换):HDU 1402 A * B Problem Plus
2016-02-29 19:35
295 查看
Calculate A * B.
Note: the length of each integer will not exceed 50000.
两个月后重打了一遍。
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.
Output
For each case, output A * B in one line.Sample Input
1 2 1000 2
Sample Output
2 2000 唉,模板题,膜的邝斌的模板。
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> 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,i*b.r+r*b.i); } }; void Rader(complex *a,int len) { int k; for(int i=1,j=len/2;i<len-1;i++) { if(i<j)swap(a[i],a[j]); k=len/2; while(j>=k) { j-=k; k>>=1; } j+=k; } } void FFT(complex *a,int len,int on) { Rader(a,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=a[k]; complex v=a[k+h/2]*w; a[k]=u+v; a[k+h/2]=u-v; w=w*wn; } } } if(on==-1) for(int i=0;i<len;i++) a[i].r/=len; } const int maxn = 200010; complex Array1[maxn],Array2[maxn]; char str1[maxn],str2[maxn]; int sum[maxn],len,len1,len2; int main() { while(~scanf("%s%s",str1,str2)) { len1=strlen(str1); len2=strlen(str2); len=1; while(len<len1*2||len<len2*2)len<<=1; for(int i=0;i<len1;i++) Array1[i]=complex(str1[len1-i-1]-'0',0); for(int i=0;i<len2;i++) Array2[i]=complex(str2[len2-i-1]-'0',0); for(int i=len1;i<len;i++) Array1[i]=complex(0,0); for(int i=len2;i<len;i++) Array2[i]=complex(0,0); FFT(Array1,len,1); FFT(Array2,len,1); for(int i=0;i<len;i++) Array1[i]=Array1[i]*Array2[i]; FFT(Array1,len,-1); memset(sum,0,sizeof(sum)); for(int i=0;i<len;i++){ sum[i]+=(int)(Array1[i].r+0.5); sum[i+1]+=sum[i]/10; sum[i]%=10; } int p=len; while(!sum[p]&&p)p--; for(;p!=-1;p--) printf("%d",sum[p]); printf("\n"); } return 0; }
两个月后重打了一遍。
#include <iostream> #include <cstring> #include <cstdio> #include <cmath> using namespace std; const int maxn=400010; 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 +(complex a){ return complex(r+a.r,i+a.i); } complex operator -(complex a){ return complex(r-a.r,i-a.i); } complex operator *(complex a){ return complex(r*a.r-i*a.i,r*a.i+a.r*i); } }A[maxn],B[maxn]; void Rader(complex *a,int len){ int k; for(int i=1,j=len>>1;i<len-1;i++){ if(i<j)swap(a[i],a[j]); k=len>>1; while(j>=k){ j-=k; k>>=1; } j+=k; } } void FFT(complex *a,int len,int on){ Rader(a,len); for(int h=2;h<=len;h<<=1){ complex wn(cos(-on*PI*2.0/h),sin(-on*PI*2.0/h)); for(int j=0;j<len;j+=h){ complex w(1,0); for(int k=j;k<j+(h>>1);k++){ complex x=a[k]; complex y=a[k+(h>>1)]*w; a[k]=x+y; a[k+(h>>1)]=x-y; w=w*wn; } } } if(on==-1) for(int i=0;i<len;i++) a[i].r/=len; return; } char s[maxn],t[maxn]; int ans[maxn]; int main(){ while(~scanf("%s%s",s,t)){ int lens=strlen(s); int lent=strlen(t),len=1; while(len<=lens+lent)len<<=1; memset(A,0,sizeof(A)); memset(B,0,sizeof(B)); for(int i=0;i<lens;i++) A[i].r=1.0*(s[lens-i-1]-'0'); for(int i=0;i<lent;i++) B[i].r=1.0*(t[lent-i-1]-'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); memset(ans,0,sizeof(ans)); int in=0; for(int i=0;i<len;i++){ ans[i]=in+floor(A[i].r+0.5); in=ans[i]/10; ans[i]%=10; } int i; for(i=len;i&&!ans[i];i--); while(~i)printf("%d",ans[i]),i--; printf("\n"); } return 0; }
相关文章推荐
- 51nod 1008 N的阶乘mod P
- 星期几(蓝桥杯)
- % 与 & 操作符
- 王爽老师汇编语言视屏下载
- <<第一行代码>>--全局获取Context技巧
- 如何演示你的App?Android录制Gif动态图教程
- WTF交换
- 算法代码实现之快速排序,Java实现
- ACM做题过程中的一些小技巧
- linux命令 time
- 解释程序和编译程序的区别
- 自适应中值滤波
- 20160229 ADO.NET连接SQL Server数据库(SqlHelper类)
- ionic splash screen 之后出现的白屏解决办法
- 常用字符串长度计算函数
- Retrofit2.0的Converter使用
- 自我介绍
- 浅谈过载保护
- PHP连接MySQL数据库过程
- 牛人的ACM经验 (转)