参考这里:http://www.cnblogs.com/pdev/p/4354705.html

      http://www.cnblogs.com/pdev/p/4354629.html

题意:求大数乘法A*B

A和B位数很长。裸高精度时间复杂度是O(nm),会完蛋

不妨回忆下裸高精度的过程:

其实乘法的那一步很类似前面介绍过的多项式快速乘法诶(⊙▽⊙)

所以就可以用前述方法计算咯,时间复杂度O(nlogn)

我是这样理解的:

每个乘数都是都是一坨时域信号(一个大混合物),然后对乘数分别进行DFT(Discrete Fourier Transform)得到频域信号(一堆纯净物)。

然后对纯净物按类别分别相加,就得到了新信号(这里即乘法结果)对应的频域信号(一堆纯净物)

然后再来一次IDFT(Inverse DFT,逆变换)把频域再转成时域(一个大混合物,即真正的乘法结果)就好啦

总结一下本题的模式:

  读入向量x、y

  int len=1;  while(len < lx*2 || len < ly*2)len<<=1;    (lx、ly分别是向量x和y的长度)

  fft(x),fft(y)

  for i=0 to len-1    x[i]=x[i]*y[i]

  ifft(x)

  for(int i = 0; i < len; i++)  sum[i] = (int)(X[i].x+0.5);    变回整数

 #include  <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <math.h>
using namespace std;
const double PI = acos(-1.0);
//复数结构体
struct Complex
{
double x,y;//实部和虚部 x+yi
Complex(double _x = 0.0,double _y = 0.0)
{
x = _x;
y = _y;
}
Complex operator -(const Complex &b)const
{
return Complex(x-b.x,y-b.y);
}
Complex operator +(const Complex &b)const
{
return Complex(x+b.x,y+b.y);
}
Complex operator *(const Complex &b)const
{
return Complex(x*b.x-y*b.y,x*b.y+y*b.x);
}
}; void change(Complex y[],int len)
{
int i,j,k;
for(i = , j = len/; i <len-; i++)
{
if(i < j)swap(y[i],y[j]);
//交换互为小标反转的元素,i<j保证交换一次
//i做正常的+1,j左反转类型的+1,始终保持i和j是反转的
k = len/;
while(j >= k)
{
j -= k;
k /= ;
}
if(j < k)j += k;
}
} void fft(Complex y[],int len,int on)
{
change(y,len);
for(int h = ; h <= len; h <<= )
{
Complex wn(cos(-on**PI/h),sin(-on**PI/h));
for(int j = ; j < len; j+=h)
{
Complex w(,);
for(int k = j; k < j+h/; k++)
{
Complex u = y[k];
Complex t = w*y[k+h/];
y[k] = u+t;
y[k+h/] = u-t;
w = w*wn;
}
}
}
if(on == -)
for(int i = ; i < len; i++)
y[i].x /= len;
} const int MAXN = ;
Complex x1[MAXN],x2[MAXN];
char str1[MAXN/],str2[MAXN/];
int sum[MAXN];
int main()
{
while(scanf("%s%s",str1,str2)==)
{
int len1 = strlen(str1);
int len2 = strlen(str2);
int len = ;
while(len < len1* || len < len2*)len<<=;
for(int i = ; i < len1; i++)
x1[i] = Complex(str1[len1--i]-'',);
for(int i = len1; i < len; i++)
x1[i] = Complex(,);
for(int i = ; i < len2; i++)
x2[i] = Complex(str2[len2--i]-'',);
for(int i = len2; i < len; i++)
x2[i] = Complex(,);
//x1[i]:x1对应的向量
//例如1989就是(9,0)、(8,0)、(9,0)、(1,0)、(0,0)、... fft(x1,len,);
fft(x2,len,); for(int i = ; i < len; i++)
x1[i] = x1[i]*x2[i]; fft(x1,len,-); for(int i = ; i < len; i++)
sum[i] = (int)(x1[i].x+0.5);
/*
for(int i=0;i<len;i++)
cout<<sum[i]<<" ";
cout<<endl;
*/
for(int i = ; i < len; i++) //此时的sum存的东西还没进位,还得处理下
{
sum[i+]+=sum[i]/;
sum[i]%=;
}
len = len1+len2-;
while(sum[len] <= && len > )len--;
for(int i = len; i >= ; i--)
printf("%c",sum[i]+'');
printf("\n");
}
return ;
}

hdu1402 FFT入门的更多相关文章

  1. TOT 傅立叶变换 FFT 入门

    HDU 1402,计算很大的两个数相乘. FFT 只要78ms,这里: 一些FFT 入门资料:http://wenku.baidu.com/view/8bfb0bd476a20029bd642d85. ...

  2. 洛谷p3803 FFT入门

    洛谷p3803 FFT入门 ps:花了我一天的时间弄懂fft的原理,感觉fft的折半很神奇! 大致谈一谈FFT的基本原理: 对于两个多项式的卷积,可以O(n^2)求出来(妥妥的暴力) 显然一个多项式可 ...

  3. FFT入门

    这篇文章会讲讲FFT的原理和代码. 先贴picks博客(又名FFT从入门到精通):http://picks.logdown.com/posts/177631-fast-fourier-transfor ...

  4. FFT 入门

    推荐博客 :https://oi.men.ci/fft-notes/ 卷积的理解 : https://www.zhihu.com/question/22298352?rf=21686447 题目链接 ...

  5. 模板:快速傅里叶变换(FFT)

    参考:http://blog.csdn.net/f_zyj/article/details/76037583 如果公式炸了请去我的csdn博客:http://blog.csdn.net/luyouqi ...

  6. bzoj2179: FFT快速傅立叶

    #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> ...

  7. 多项式FFT相关模板

    自己码了一个模板...有点辛苦...常数十分大,小心使用 #include <iostream> #include <stdio.h> #include <math.h& ...

  8. 3-idiots hdu4609 母函数+FFT 组合数学题

    http://acm.hdu.edu.cn/showproblem.php?pid=4609 题意:1e5个数,求取三个数能形成三角形的概率. 题解(这怎么会是fft入门题QAQ): 概率的算法就是三 ...

  9. HDU 1402 大数乘法 FFT、NTT

    A * B Problem Plus Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

随机推荐

  1. git 保存本地更改而不需要推到远程

    git commit 修改到本地分支 repo sync . 更新分支 git checkout local 切换到本地分支 git rebase 远程 更新远程分支到本地并且将本地分支节点推到最顶

  2. [转]C#压缩打包文件

    /// <summary> /// 压缩和解压文件 /// </summary> public class ZipClass { /// <summary> /// ...

  3. 学习C++.Primer.Plus 5 循环和关系表达式

    C++将赋值表达式的值定义为左侧成员的值 赋值操作符是自右向左结合的 cout.setf(ios:: boolalpha);//调用设置标记,命令cout输出true或false,而非1或0. 任何表 ...

  4. vmware安装cent os 6.5 + oracle 11g xe + jboss eap 6.2 + weblogic 12c+ webshpere mq 7.5

    前言: mac系统发展速度确实很快,短短数年,mac os上已经能网银支付(中行.招行.工商.支付宝等均已全面支持mac os了),windows上的经典常用软件:qq.飞信.旺旺.有道词典.有道云笔 ...

  5. 机械大楼电梯控制项目软件 -- github团队组建

    目前在Github网站上建立了机械大楼电梯控制项目软件的软件仓库(Repository),提供了软件功能需求说明文档和Automation Studio程序模板.地址为 https://github. ...

  6. iptables规则组成

    一.四张表五条链 组成部分:四张表 + 5条链(Hook point) + 规则 四张表:filter nat mangle raw 五条链:PREROUTING INPUT FORWARD OUTP ...

  7. java并发:同步容器&并发容器

    第一节 同步容器.并发容器 1.简述同步容器与并发容器 在Java并发编程中,经常听到同步容器.并发容器之说,那什么是同步容器与并发容器呢?同步容器可以简单地理解为通过synchronized来实现同 ...

  8. Node基础:url查询参数解析之querystring

    模块概述 在nodejs中,提供了querystring这个模块,用来做url查询参数的解析,使用非常简单. 模块总共有四个方法,绝大部分时,我们只会用到 .parse(). .stringify() ...

  9. 架构系列:ASP.NET 项目结构搭建

    我们头开始,从简单的单项目解决方案,逐步添加业务逻辑的约束,从应用逻辑和领域逻辑两方面考虑,从简单的单个项目逐步搭建一个多项目的解决方案.主要内容:(1)搭建应用逻辑和领域逻辑都简单的单项目 (2)为 ...

  10. <string> 与<string.h>、<cstring>的区别

    <string.h> <string.h>是C版本的头文件,包含比如strcpy.strcat之类的字符串处理函数. <cstring> 在C++标准化(1998年 ...