• HDU 1402 A * B Problem Plus FFT


    A * B Problem Plus

    题目连接:

    http://acm.hdu.edu.cn/showproblem.php?pid=1402

    Description

    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

    Hint

    题意

    题解:

    考虑变成系数的形式,显然就是两个的多项式乘法

    然后转化成FFT,直接莽一波就完了。

    代码

    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    
    using namespace std;
    
    
    const int N = 500005;
    const double pi = acos(-1.0);
    
    char s1[N],s2[N];
    int len,res[N];
    
    struct Complex
    {
        double r,i;
    	Complex(double r=0,double i=0):r(r),i(i) {};
    	Complex operator+(const Complex &rhs)
    	{
    		return Complex(r + rhs.r,i + rhs.i);
    	}
    	Complex operator-(const Complex &rhs)
    	{
    		return Complex(r - rhs.r,i - rhs.i);
    	}
    	Complex operator*(const Complex &rhs)
    	{
    		return Complex(r*rhs.r - i*rhs.i,i*rhs.r + r*rhs.i);
    	}
    } va[N],vb[N];
    
    void rader(Complex F[],int len)	//len = 2^M,reverse F[i] with  F[j] j为i二进制反转
    {
    	int j = len >> 1;
    	for(int i = 1;i < len - 1;++i)
    	{
    		if(i < j) swap(F[i],F[j]);	// reverse
    		int k = len>>1;
    		while(j>=k)
    		{
    			j -= k;
    			k >>= 1;
    		}
    		if(j < k) j += k;
    	}
    }
    
    void FFT(Complex F[],int len,int t)
    {
    	rader(F,len);
    	for(int h=2;h<=len;h<<=1)
    	{
    		Complex wn(cos(-t*2*pi/h),sin(-t*2*pi/h));
    		for(int j=0;j<len;j+=h)
    		{
    			Complex E(1,0);	//旋转因子
    			for(int k=j;k<j+h/2;++k)
    			{
    				Complex u = F[k];
    				Complex v = E*F[k+h/2];
    				F[k] = u+v;
    				F[k+h/2] = u-v;
    				E=E*wn;
    			}
    		}
    	}
    	if(t==-1)	//IDFT
    		for(int i=0;i<len;++i)
    			F[i].r/=len;
    }
    
    void Conv(Complex a[],Complex b[],int len) //求卷积
    {
    	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);
    }
    
    void init(char *s1,char *s2)
    {
    	int n1 = strlen(s1),n2 = strlen(s2);
    	len = 1;
    	while(len < 2*n1 || len < 2*n2) len <<= 1;
    	int i;
    	for(i=0;i<n1;++i)
    	{
    		va[i].r = s1[n1-i-1]-'0';
    		va[i].i = 0;
    	}
    	while(i<len)
    	{
    		va[i].r = va[i].i = 0;
    		++i;
    	}
    	for(i=0;i<n2;++i)
    	{
    		vb[i].r = s2[n2-i-1]-'0';
    		vb[i].i = 0;
    	}
    	while(i<len)
    	{
    		vb[i].r = vb[i].i = 0;
    		++i;
    	}
    }
    
    void gao()
    {
    	Conv(va,vb,len);
    	memset(res,0,sizeof res);
    	for(int i=0;i<len;++i)
    	{
    		res[i]=va[i].r + 0.5;
    	}
    	for(int i=0;i<len;++i)
    	{
    		res[i+1]+=res[i]/10;
    		res[i]%=10;
    	}
    	int high = 0;
    	for(int i=len-1;i>=0;--i)
    	{
    		if(res[i])
    		{
    			high = i;
    			break;
    		}
    	}
    	for(int i=high;i>=0;--i) putchar('0'+res[i]);
    	puts("");
    }
    
    
    int main()
    {
    	while(scanf("%s %s",s1,s2)==2)
    	{
    		init(s1,s2);
    		gao();
    	}
    	return 0;
    }
  • 相关阅读:
    d
    今天刚注册,测试下
    关于Hadoop的简单介绍
    leveldb 阅读笔记 (2) 简易测试框架
    leveldb 阅读笔记(1) 内存分配器 Arena
    数论
    伴随网站
    convenience website
    大佬独特的骗分技巧
    动态规划
  • 原文地址:https://www.cnblogs.com/qscqesze/p/5379677.html
Copyright © 2020-2023  润新知