hdu 1402 A * B Problem Plus FFT

19 篇文章 0 订阅
8 篇文章 0 订阅
/*
hdu 1402 A * B Problem Plus FFT

这是我的第二道FFT的题

第一题是完全照着别人的代码敲出来的,也不明白是什么意思

这个代码是在前一题的基础上改的

做完这个题,我才有点儿感觉,原来FFT在这里就是加速大整数乘法而已

像前一题,也是一个大整数乘法,然后去掉一些非法的情况

*/
#pragma warning(disable : 4786)
#pragma comment(linker, "/STACK:102400000,102400000")
#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <vector>
#include <stack>
#include <queue>//priority_queue
#include <bitset>
#include <complex>
#include <utility>
/*
**make_pair()
**/
using namespace std;
const double eps=1e-8;
const double PI=acos(-1.0);
const int inf=0x7fffffff;
template<typename T> inline T MIN(T a,T b){return a<b?a:b;}
template<typename T> inline T MAX(T a,T b){return a>b?a:b;}
template<typename T> inline T SQR(T a){return a*a;}
inline int dbcmp(double a){return a>eps?(1):(a<(-eps)?(-1):0);}

typedef __int64 LL;
int n;
const int size=400040;
int data[size/4];
int sum[size];
complex<double> x1[size],num1[size],num2[size];



void change(complex<double> y[],int len)
{
    int i,j,k;
    for(i = 1, j = len/2;i < len-1;i++)
    {
        if(i < j)swap(y[i],y[j]);
        k = len/2;
        while( j >= k)
        {
            j -= k;
            k /= 2;
        }
        if(j < k)j += k;
    }
}
void fft(complex<double> y[],int len,int on)
{
    change(y,len);
    for(int h = 2;h <= len;h <<= 1)
    {
        complex<double> wn(cos(-on*2*PI/h),sin(-on*2*PI/h));
        for(int j = 0;j < len;j += h)
        {
            complex<double> w(1,0);
            for(int k = j;k < j+h/2;k++)
            {
                complex<double> u = y[k];
                complex<double> t = w*y[k+h/2];
                y[k] = u+t;
                y[k+h/2] = u-t;
                w = w*wn;
            }
        }
    }
    if(on == -1)
        for(int i = 0;i < len;i++)
            y[i].real(y[i].real()/len);
}
char s1[size];
char s2[size];
int main() {
	// your code goes here
	int t,i,j;
	int len,len1,len2;
	//cin>>t;
	while(gets(s1))
	{
		gets(s2);
		memset(num1,0,sizeof(num1));
		memset(num2,0,sizeof(num2));
		len1=strlen(s1);
		len2=strlen(s2);
		//printf("%d %d",len1,len2);
		len=1;
		while(len<2*len1||len<len2*2) len<<=1;
		for(i=len1-1,j=0;i>=0;--i,++j)
		{
			num1[j]=complex<double>(s1[i]-'0',0);
		}
		while(j<=len)
		{
			num1[j]=complex<double>(0,0);
			++j;
		}
		for(i=len2-1,j=0;i>=0;--i,++j)
		{
			num2[j]=complex<double>(s2[i]-'0',0);
		}
		while(j<=len)
		{
			num2[j]=complex<double>(0,0);
			++j;
		}
		fft(num1,len,1);
		fft(num2,len,1);
		for(i=0;i<len;++i)
		{
			num1[i]=num1[i]*num2[i];
		}
		fft(num1,len,-1);

		for(i=0;i<len;++i)
		{
			sum[i]=(int)(num1[i].real()+0.5);
		}
		for(i=0;i<len;++i)
		{
			sum[i+1]+=sum[i]/10;
			sum[i]=sum[i]%10;
		}
		len=len1+len2-1;
		while(sum[len]<=0&&len>0) --len;
		for(;len>=0;--len)
		{
			printf("%c",sum[len]+'0');
		}
		printf("\n");
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值