您的位置:首页 > 其它

FFT(快速傅立叶变换):HDU 1402 A * B Problem Plus

2016-02-29 19:35 295 查看
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.

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: