HDU 1402 A * B Problem Plus (FFT求高精度乘法)
A * B Problem Plus
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 9413 Accepted Submission(s): 1468
Note: the length of each integer will not exceed 50000.
2
1000
2
2000
神奇的FFT。
如果是乘法,位数为n和位数为m的相乘,需要n*m次的乘法运算。
FFT在数字信号处理学过,但是第一次用来做这类题目,神奇啊。
乘法其实就是做线性卷积。
用DFT得方法可以求循环卷积,但是当循环卷积长度L≥N+M-1,就可以做线性卷积了。
使用FFT将两个数列转换成傅里叶域,在这的乘积就是时域的卷积。
给几个学习的链接吧:
http://wenku.baidu.com/view/8bfb0bd476a20029bd642d85.html (这主要看那个FFT的流程图)
http://wlsyzx.yzu.edu.cn/kcwz/szxhcl/kechenneirong/jiaoan/jiaoan3.htm 这有DFT的原理。
整理了个模板,感觉很赞!
#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 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,r*b.i+i*b.r);
}
};
/*
* 进行FFT和IFFT前的反转变换。
* 位置i和 (i二进制反转后位置)互换
* len必须去2的幂
*/
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;
}
}
/*
* 做FFT
* len必须为2^k形式,
* on==1时是DFT,on==-1时是IDFT
*/
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].r /= 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(,);
//求DFT
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].r+0.5);
for(int i = ;i < len;i++)
{
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 ;
}
HDU 1402 A * B Problem Plus (FFT求高精度乘法)的更多相关文章
- HDU - 1402 A * B Problem Plus (FFT实现高精度乘法)
题意:计算A*B,A,B均为长度小于50000的整数. 这是FFT在大整数相乘中的一个应用,我本来想用NTT做的,但NTT由于取模很可能取炸,所以base必须设得很小,而且效率也比不上FFT. A和B ...
- hdu 1402 A * B Problem Plus FFT
/* hdu 1402 A * B Problem Plus FFT 这是我的第二道FFT的题 第一题是完全照着别人的代码敲出来的,也不明白是什么意思 这个代码是在前一题的基础上改的 做完这个题,我才 ...
- HDU - 1402 A * B Problem Plus FFT裸题
http://acm.hdu.edu.cn/showproblem.php?pid=1402 题意: 求$a*b$ 但是$a$和$b$的范围可以达到 $1e50000$ 题解: 显然...用字符串模拟 ...
- HDU 1402 A * B Problem Plus (FFT模板题)
FFT模板题,求A*B. 用次FFT模板需要注意的是,N应为2的幂次,不然二进制平摊反转置换会出现死循环. 取出结果值时注意精度,要加上eps才能A. #include <cstdio> ...
- SPOJ - VFMUL - Very Fast Multiplication FFT加速高精度乘法
SPOJ - VFMUL:https://vjudge.net/problem/SPOJ-VFMUL 这是一道FFT求高精度的模板题. 参考:https://www.cnblogs.com/Rabbi ...
- P1919 FFT加速高精度乘法
P1919 FFT加速高精度乘法 传送门:https://www.luogu.org/problemnew/show/P1919 题意: 给出两个n位10进制整数x和y,你需要计算x*y. 题解: 对 ...
- HDU 1402 A * B Problem Plus 快速傅里叶变换 FFT 多项式
http://acm.hdu.edu.cn/showproblem.php?pid=1402 快速傅里叶变换优化的高精度乘法. https://blog.csdn.net/ggn_2015/artic ...
- FFT实现高精度乘法
你应该知道$FFT$是用来处理多项式乘法的吧. 那么高精度乘法和多项式乘法有什么关系呢? 观察这样一个$20$位高精度整数$11111111111111111111$ 我们可以把它处理成这样的形式:$ ...
- BZOJ2179: FFT快速傅立叶 FFT实现高精度乘法
Code: #include <cstdio> #include <algorithm> #include <cmath> #include <cstring ...
随机推荐
- ios上传图片显示方向错误问题
IOS 上传图片方向显示错误问题 问题描述 在使用苹果手机上传图片的时候,发现传完的图片显示出来方向是错误的,竖着的图片会变成横着显示(少部分安卓手机也存在这个问题) 产生原因 ios 相机加入了方向 ...
- [51nod1009]数字1的数量
解题关键:数位dp,对每一位进行考虑,通过过程得出每一位上1出现的次数 1位数的情况: 在解法二中已经分析过,大于等于1的时候,有1个,小于1就没有. 2位数的情况: N=13,个位数出现的1的次数为 ...
- 【bzoj3196-二逼平衡树】线段树套平衡树
http://acm.hust.edu.cn/vjudge/problem/42297 [题目描述] 写一种数据结构,来维护一个有序数列,其中需要提供以下操作: 1.查询k在区间内的排名 2.查询区间 ...
- python面向对象之继承与派生
一.继承 继承是一种创建新的类的方式,在python中,新建的类可以继承自一个或者多个父类,原始类称为基类或超类,新建的类称为派生类或子类. python中类的继承分为:单继承和多继承,如果是多继承的 ...
- IC卡的传输协议(2)-块传输协议T=1续【转】
转自:http://bbs.ednchina.com/BLOG_ARTICLE_172025.HTM (3)容错操作 先来看一下容错的规则定义. * 复位应答后,第一个数据块是由终端发往IC卡的,而且 ...
- Vmware中安装和卸载Linux 16.04.3
1.先去这个链接 https://www.ubuntu.com/download ,下载ubuntu镜像,也就是下图的download选项 2.下载后到虚拟机里创建一个新的虚拟机,然后按照博客 htt ...
- java小工具——timer
定时器Timer 用途:做定时器用的. public static void main(String[] args) { Timer timer = new Timer(); timer.schedu ...
- 某dp题
[NOI联考by ysy]庆典 2016年6月17日1,1040 [题目描述] 战狂在昌和帝国的首都法法城召开了庆典,向一万名最杰出的士兵分发了用魔法猪做的猪肉饺子,士兵们吃了猪肉饺子后,战斗力大幅提 ...
- C# 调试程序时如何输入命令行参数
调试程序时如何输入命令行参数http://www.a769.com/archives/320.html 开发命令行程序时,我们会疑惑,从那里输入参数呢?请看下面的教程,让你摆脱困扰. 1.点击菜单栏: ...
- python 如何放心干净的卸载模块
windows系统: C:\selenium-2.43.0>python setup.py install --record ./record.txt C:\selenium-2.43.0> ...