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

题意:

  求$a*b$ 但是$a$和$b$的范围可以达到 $1e50000$

题解:

  显然...用字符串模拟的大数或者压位的大数是无法胜任这种计算的....

  然后,2个大整数相乘,可以理解为卷积,所以就用快速傅里叶变换(FFT)来加速他

  模板题

  简单总结一下对FFT的认知:

FFT用于算卷积,卷积可以理解为两个多项式相乘
显然复杂度是$O(n^2)$的 但是fft可以优化为$O(nlogn)$
如何优化,
考虑2个点确定直线,3个点确定抛物线,$n+1$个点确定了$n$次多项式
我们用$n+1$个点$(x_i,y_i)$表达了原来的式子
如何用点值表达卷积(多项式相乘)?
式子展开可以知道,$x_i$确定的时候,对于点值表达式就对应了点$(x_i,f(x_i)*g(x_i))$
也就是可以$O(1)$得到一个点答案,$n$个点就是$O(n)$
那问题又来了,$n+1$个点的$(x_i,y_i)$,每次求解一次多项式的值,需要$O(n)$
也就是$O(n^2)$复杂度,依然超时
所以,现在考虑如何快速的算多项式的值
因为$x_i$我们可以自己定义,因此利用虚根的特殊性质,我们就能分治处理了
就可以复杂度$O(nlogn)$的得到点值表达式
然后$O(n)$的算点值表达式的值
然后逆运算回到答案

  1. #include <bits/stdc++.h>
  2. #define ll long long
  3. #define usd unsigned
  4. #define IO ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
  5. #define rep(ii,a,b) for(int ii=a;ii<=b;++i)
  6. #define per(ii,a,b) for(int ii=b;ii>=a;--i)
  7. #define show(x) cout<<#x<<"="<<x<<endl
  8. #define show2(x,y) cout<<#x<<"="<<x<<" "<<#y<<"="<<y<<endl
  9. #define show3(x,y,z) cout<<#x<<"="<<x<<" "<<#y<<"="<<y<<" "<<#z<<"="<<z<<endl
  10. #define show4(w,x,y,z) cout<<#w<<"="<<w<<" "<<#x<<"="<<x<<" "<<#y<<"="<<y<<" "<<#z<<"="<<z<<endl
  11. #define showa(a,b) cout<<#a<<'['<<b<<"]="<<a[b]<<endl
  12. #define pii pair<int,int>
  13. #define cp complex<double>//<complex>头文件里的东西
  14. using namespace std;
  15. const int maxn=2e5+10;
  16. const int maxm=2e6+10;
  17. const int INF=0x3f3f3f3f;
  18. const int mod=1e9+7;
  19. int casn,n,m,k;
  20. const double pi=acos(-1.0);
  21. int lena,lenb,len,pw,ans[maxn],rr[maxn];
  22. cp a[maxn] ,b[maxn];
  23. char sa[maxn],sb[maxn];
  24. void fft(cp *a,int f){//递归分治太慢,用迭代实现
  25. rep(i,0,n-1) if(i<rr[i]) swap(a[i],a[rr[i]]);//分治原来的数组
  26. for(int i=1;i<n;i<<=1){
  27. cp wn(cos(pi/i),sin(f*pi/i)),x,y;//计算虚根
  28. for(int j=0;j<n;j+=(i<<1)){
  29. cp w(1,0);
  30. for(int k=0;k<i;++k,w*=wn){
  31. x=a[j+k],y=w*a[i+j+k];
  32. a[j+k]=x+y;
  33. a[i+j+k]=x-y;
  34. }
  35. }
  36. }
  37. }
  38. int main(){
  39. while(~scanf("%s%s",sa,sb)){
  40. n=1;
  41. len=pw=0;
  42. memset(ans,0,sizeof ans);
  43. lena=strlen(sa);
  44. lenb=strlen(sb);
  45. while(n<=lena+lenb) n<<=1,++pw;
  46. rep(i,0,lena-1) a[i]=sa[lena-i-1]-'0';
  47. rep(i,lena,n) a[i]=0;
  48. rep(i,0,lenb-1) b[i]=sb[lenb-i-1]-'0';
  49. rep(i,lenb,n) b[i]=0;
  50. rep(i,0,n) rr[i]=(rr[i>>1]>>1)|((i&1)<<(pw-1));//分治中的二进制规律,因此预处理参数
  51. fft(a,1);//DFT a
  52. fft(b,1);//DFT b
  53. rep(i,0,n) a[i]*=b[i];
  54. fft(a,-1);//IDFT a*b
  55. rep(i,0,lena+lenb) {
  56. ans[i]+=int(a[i].real()/n+0.5);
  57. ans[i+1]+=ans[i]/10;
  58. ans[i]%=10;
  59. if(ans[i]>0) len=i;
  60. }
  61. per(i,0,len){
  62. putchar (ans[i]+'0');
  63. }
  64. puts("");
  65. }
  66. return 0;
  67. }

  

HDU - 1402 A * B Problem Plus FFT裸题的更多相关文章

  1. HDU 1402 A * B Problem Plus (FFT模板题)

    FFT模板题,求A*B. 用次FFT模板需要注意的是,N应为2的幂次,不然二进制平摊反转置换会出现死循环. 取出结果值时注意精度,要加上eps才能A. #include <cstdio> ...

  2. hdu 1402 A * B Problem Plus FFT

    /* hdu 1402 A * B Problem Plus FFT 这是我的第二道FFT的题 第一题是完全照着别人的代码敲出来的,也不明白是什么意思 这个代码是在前一题的基础上改的 做完这个题,我才 ...

  3. HDU 1402 A * B Problem Plus (FFT求高精度乘法)

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

  4. HDU - 1402 A * B Problem Plus (FFT实现高精度乘法)

    题意:计算A*B,A,B均为长度小于50000的整数. 这是FFT在大整数相乘中的一个应用,我本来想用NTT做的,但NTT由于取模很可能取炸,所以base必须设得很小,而且效率也比不上FFT. A和B ...

  5. HDU 5832 A water problem(某水题)

    p.MsoNormal { margin: 0pt; margin-bottom: .0001pt; text-align: justify; font-family: Calibri; font-s ...

  6. HDU 1402 A * B Problem Plus ——(大数乘法,FFT)

    因为刚学fft,想拿这题练练手,结果WA了个爽= =. 总结几点犯的错误: 1.要注意处理前导零的问题. 2.一定要注意数组大小的问题.(前一个fft的题因为没用到b数组,所以b就没管,这里使用了b数 ...

  7. hdu 2993 MAX Average Problem(斜率DP入门题)

    题目链接:hdu 2993 MAX Average Problem 题意: 给一个长度为 n 的序列,找出长度 >= k 的平均值最大的连续子序列. 题解: 这题是论文的原题,请参照2004集训 ...

  8. HDU 1402 A * B Problem Plus 快速傅里叶变换 FFT 多项式

    http://acm.hdu.edu.cn/showproblem.php?pid=1402 快速傅里叶变换优化的高精度乘法. https://blog.csdn.net/ggn_2015/artic ...

  9. hdu 1402 A * B Problem Plus (FFT模板)

    A * B Problem Plus Problem Description Calculate A * B. Input Each line will contain two integers A ...

随机推荐

  1. vs code解决golang开发环境问题 dial tcp 216.239.37.1:443: connectex: A connection attempt failed

    安装插件是出现 如下错误提示, https fetch failed: Get https://golang.org/x/tools/cmd/gorename?go-get=1: dial tcp 2 ...

  2. Django多表操作

    多表创建 创建模型 下面通过一个简单的图书管理系统,来阐述多表的创建和查询操作 在视图函数里里定义如下代码 from django.db import models class Book(models ...

  3. Kettle 和数据建模的几个学习资料

    视频课程: 1. 初建军的   [慕课大巴分享]炼数成金——深入BI - Kettle 篇 基础书:1. Kettle 3.0 用户手册, 文件名为: ETL工具Kettle用户手册(上).pdf, ...

  4. js对象,字符串 互相 转换

     JSON.stringify(jsonobj);    //可以将json对象转换成json字符串 反过来: JSON.parse(jsonstr);     //可以将json字符串转换成json ...

  5. Android adb shell 常用命令

    Ø  简介 adb 命令是 Android SDK 中自带的一个调试工具,可以调试电脑中的手机或者模拟器,使用 adb 命令前需要将 sdk 中的 platform-tools 目录添加到环境变量中. ...

  6. 《Python数据可视化编程实战》

    第一章:准备工作环境 WinPython-32bit-3.5.2.2Qt5.exe 1.1 设置matplotlib参数 配置模板以方便各项目共享 D:\Bin\WinPython-32bit-3.5 ...

  7. QWidget扩充父子关系

    childAt(x, y)      获取在指定坐标处的子控件 parentWidget()      获取指定控件的父控件 s=label.parentWidget()     #返回label的父 ...

  8. 获取当前div以外所有部分

    $("功能区域的id").click(function(e){ $(this).show(); e.stopPropagation();//阻止冒泡 }); $("父类区 ...

  9. Java Web之JSTL标准标签库总结

    [文档整理系列] Java Web之JSTL标准标签库总结

  10. 剑指Offer题解索引

    数组 数组中重复的数字 二维数组中的查找 构建乘积数组 字符串 替换空格 字符流中第一个不重复的字符 表示数值的字符串 递归和循环 斐波那契数列 跳台阶 变态跳台阶 矩形覆盖 链表 从尾到头打印链表 ...