zoukankan      html  css  js  c++  java
  • 【FFT】hdu1402 A * B Problem Plus

    FFT板子。

    将大整数看作多项式,它们的乘积即多项式的乘积在x=10处的取值。

    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define EPS 1e-8
    const double PI = acos(-1.0);
    struct Complex{
    	double real,image;
    	Complex(double _real,double _image){
    		real=_real;
    		image=_image;
    	}
    	Complex(){}
    };
    Complex operator + (const Complex &c1,const Complex &c2){
    	return Complex(c1.real+c2.real,c1.image+c2.image);
    }
    Complex operator - (const Complex &c1,const Complex &c2){
    	return Complex(c1.real-c2.real,c1.image-c2.image);
    }
    Complex operator * (const Complex &c1,const Complex &c2){
    	return Complex(c1.real*c2.real-c1.image*c2.image,c1.real*c2.image+c1.image*c2.real);
    }
    int rev(int id,int len){
        int ret=0;
        for(int i=0;(1<<i)<len;++i){
    		ret<<=1;
    		if(id&(1<<i)){
    			ret|=1;
    		}
    	}
    	return ret;
    }
    Complex tmp[200100];
    //µ±DFT==1ʱÊÇDFT, DFT==-1ʱÔòÊÇÄæDFT
    void IterativeFFT(Complex A[],int len, int DFT){//¶Ô³¤¶ÈΪlen(2µÄÃÝ)µÄÊý×é½øÐÐDFT±ä»»
    	for(int i=0;i<len;++i){
    		tmp[rev(i,len)]=A[i];
    	}
    	for(int i=0;i<len;++i){
    		A[i]=tmp[i];
    	}
    	for(int s=1;(1<<s)<=len;++s){
    		int m=(1<<s);
    		Complex wm=Complex(cos(DFT*2*PI/m),sin(DFT*2*PI/m));
    		for(int k=0;k<len;k+=m){//ÕâÒ»²ã½áµã°üº¬µÄÊý×éÔªËظöÊý¶¼ÊÇ(1<<s)
    			Complex w=Complex(1,0);
    			for(int j=0;j<(m>>1);++j){//ÕÛ°ëÒýÀí£¬¸ù¾ÝÁ½¸ö×Ó½Úµã¼ÆË㸸½Úµã
    				Complex t=w*A[k+j+(m>>1)];
    				Complex u=A[k+j];
    				A[k+j]=u+t;
    				A[k+j+(m>>1)]=u-t;
    				w=w*wm;
    			}
    		}
    	}
    	if(DFT==-1){
    		for(int i=0;i<len;++i){
    			A[i].real/=len;
    			A[i].image/=len;
    		}
    	}
    }
    Complex a[200100],b[200100];
    int ans[200100];
    char s1[50010],s2[50010];
    int main(){
    //	freopen("a.in","r",stdin);
    	while(scanf("%s%s",s1,s2)!=EOF){
    		memset(a,0,sizeof(a));
    		memset(b,0,sizeof(b));
    		memset(ans,0,sizeof(ans));
    		int len1=strlen(s1),len2=strlen(s2),len;
    		if((len1==1 && s1[0]=='0') || (len2==1 && s2[0]=='0')){
    			puts("0");
    			continue;
    		}
    		for(int i=0;;++i){
    			if((1<<i)>=len1+len2){
    				len=(1<<i);
    				break;
    			}
    		}
    		for(int i=len1-1,j=0;i>=0;--i,++j){
    			a[j]=Complex(s1[i]-'0',0);
    		}
    		for(int i=len2-1,j=0;i>=0;--i,++j){
    			b[j]=Complex(s2[i]-'0',0);
    		}
    		IterativeFFT(a,len,1);
    		IterativeFFT(b,len,1);
    		for(int i=0;i<len;++i){
    			a[i]=a[i]*b[i];
    		}
    		IterativeFFT(a,len,-1);
    		for(int i=0;i<len;++i){
    			ans[i]=(int)(a[i].real+0.5);
    		}
    		for(int i=0;i<len1+len2-1;++i){
    			ans[i+1]+=ans[i]/10;
    			ans[i]%=10;
    		}
    		for(int i=len;i>=0;--i){
    			if(ans[i]!=0){
    				for(int j=i;j>=0;--j){
    					printf("%d",ans[j]);
    				}
    				puts("");
    				break;
    			}
    		}
    	}
    	return 0;
    }
  • 相关阅读:
    集训第六周 O题
    集训第六周 M题
    集训第六周 矩阵快速幂 K题
    集训第六周 数学概念与方法 计数 排列 L题
    集训第六周 数学概念与方法 J题 数论,质因数分解
    集训第六周 数学概念与方法 数论 线性方程 I题
    集训第六周 数学概念与方法 概率 N题
    HUAS Summer Contest#4 D题 DP
    集训第六周 数学概念与方法 数论 筛素数 H题
    C语言之六大排序算法
  • 原文地址:https://www.cnblogs.com/autsky-jadek/p/6642449.html
Copyright © 2011-2022 走看看