[hdu1402]A * B Problem Plus(FFT模板题)
解题关键:快速傅里叶变换fft练习。
关于结果多项式长度的确定,首先将短多项式扩展为长多项式,然后扩展为两倍。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<iostream>
#include<cmath>
#include<complex>
#define N 131072
#define pi acos(-1.0)
using namespace std;
typedef long long ll;
typedef complex<double> E;
int n,m,L;
char ch1[N],ch2[N];
int R[N],c[N];
E a[N],b[N];
//高效迭代实现fft
void fft(E *a,int f){
for(int i=;i<n;i++)if(i<R[i])swap(a[i],a[R[i]]);//位逆序置换
for(int i=;i<n;i<<=){
E wn(cos(pi/i),f*sin(pi/i));
for(int j=;j<n;j+=(i<<)){
E w(,);
for(int k=;k<i;k++,w*=wn){//蝴蝶操作
E x=a[j+k],y=w*a[j+k+i];
a[j+k]=x+y;a[j+k+i]=x-y;
}
}
}
if(f==-)for(int i=;i<n;i++)a[i]/=n;
} int main(){
while(scanf("%s%s",ch1,ch2)!=EOF){
memset(a,,sizeof a);
memset(b,,sizeof b);
memset(c,,sizeof c);
L=;
int len1=strlen(ch1),len2=strlen(ch2);
for(int i=;i<len1;i++)a[i]=ch1[len1-i-]-'';
for(int i=;i<len2;i++)b[i]=ch2[len2-i-]-'';
for(n=;n<*len1||n<*len2;n<<=)L++;
for(int i=;i<n;i++)R[i]=(R[i>>]>>)|((i&)<<(L-));//打印逆序表
fft(a,);fft(b,);//dft
for(int i=;i<n;i++)a[i]*=b[i];
fft(a,-);//idft
for(int i=;i<n;i++)c[i]=(int)(a[i].real()+0.1);
for(int i=;i<n;i++)
if(c[i]>=){
c[i+]+=c[i]/,c[i]%=;
}
while(n>&&!c[n]) n--;
for(;n>=;--n) printf("%d",c[n]);
puts("");
}
return ;
}
memset改一下。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<iostream>
#include<cmath>
#include<complex>
#define N 131072
#define pi acos(-1.0)
using namespace std;
typedef long long ll;
typedef complex<double> E;
int n,m,L;
char ch1[N],ch2[N];
int R[N],c[N];
E a[N],b[N];
//高效迭代实现fft
void fft(E *a,int f){
for(int i=;i<n;i++)if(i<R[i])swap(a[i],a[R[i]]);//位逆序置换
for(int i=;i<n;i<<=){
E wn(cos(pi/i),f*sin(pi/i));
for(int j=;j<n;j+=(i<<)){
E w(,);
for(int k=;k<i;k++,w*=wn){//蝴蝶操作
E x=a[j+k],y=w*a[j+k+i];
a[j+k]=x+y;a[j+k+i]=x-y;
}
}
}
if(f==-)for(int i=;i<n;i++)a[i]/=n;
} int main(){
while(scanf("%s%s",ch1,ch2)!=EOF){
memset(c,,sizeof c);
int len1=strlen(ch1),len2=strlen(ch2);
L=;
for(n=;n<*len1||n<*len2;n<<=)L++;
for(int i=;i<n;i++) a[i]=b[i]=;
for(int i=;i<len1;i++)a[i]=ch1[len1-i-]-'';
for(int i=;i<len2;i++)b[i]=ch2[len2-i-]-'';
for(int i=;i<n;i++)R[i]=(R[i>>]>>)|((i&)<<(L-));//打印逆序表
fft(a,);fft(b,);//dft
for(int i=;i<n;i++)a[i]*=b[i];
fft(a,-);//idft
for(int i=;i<n;i++)c[i]=(int)(a[i].real()+0.1);
for(int i=;i<n;i++)
if(c[i]>=){
c[i+]+=c[i]/,c[i]%=;
}
while(n>&&!c[n]) n--;
for(;n>=;--n) printf("%d",c[n]);
puts("");
}
return ;
}
最后试了下,len1+len2就可以。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<iostream>
#include<cmath>
#include<complex>
#define N 131072
#define pi acos(-1.0)
using namespace std;
typedef long long ll;
typedef complex<double> E;
int n,m,L;
char ch1[N],ch2[N];
int R[N],c[N];
E a[N],b[N];
//高效迭代实现fft
void fft(E *a,int f){
for(int i=;i<n;i++)if(i<R[i])swap(a[i],a[R[i]]);//位逆序置换
for(int i=;i<n;i<<=){
E wn(cos(pi/i),f*sin(pi/i));
for(int j=;j<n;j+=(i<<)){
E w(,);
for(int k=;k<i;k++,w*=wn){//蝴蝶操作
E x=a[j+k],y=w*a[j+k+i];
a[j+k]=x+y;a[j+k+i]=x-y;
}
}
}
if(f==-)for(int i=;i<n;i++)a[i]/=n;
} int main(){
while(scanf("%s%s",ch1,ch2)!=EOF){
memset(c,,sizeof c);
int len1=strlen(ch1),len2=strlen(ch2);
L=;
for(n=;n<len1+len2;n<<=)L++;
for(int i=;i<=n;i++) a[i]=b[i]=;
for(int i=;i<len1;i++)a[i]=ch1[len1-i-]-'';
for(int i=;i<len2;i++)b[i]=ch2[len2-i-]-'';
for(int i=;i<n;i++)R[i]=(R[i>>]>>)|((i&)<<(L-));//打印逆序表
fft(a,);fft(b,);//dft
for(int i=;i<n;i++)a[i]*=b[i];
fft(a,-);//idft
for(int i=;i<n;i++)c[i]=(int)(a[i].real()+0.1);
for(int i=;i<n;i++)
if(c[i]>=){
c[i+]+=c[i]/,c[i]%=;
}
while(n>&&!c[n]) n--;
for(;n>=;--n) printf("%d",c[n]);
puts("");
}
return ;
}
[hdu1402]A * B Problem Plus(FFT模板题)的更多相关文章
- HDU 1402 A * B Problem Plus (FFT模板题)
FFT模板题,求A*B. 用次FFT模板需要注意的是,N应为2的幂次,不然二进制平摊反转置换会出现死循环. 取出结果值时注意精度,要加上eps才能A. #include <cstdio> ...
- HDU - 1402 A * B Problem Plus FFT裸题
http://acm.hdu.edu.cn/showproblem.php?pid=1402 题意: 求$a*b$ 但是$a$和$b$的范围可以达到 $1e50000$ 题解: 显然...用字符串模拟 ...
- 51nod 1028 大数乘法 V2 【FFT模板题】
题目链接 模板题.. #include<bits/stdc++.h> using namespace std; typedef int LL; typedef double db; nam ...
- P1919 【模板】A*B Problem升级版 /// FFT模板
题目大意: 给定l,输入两个位数为l的数A B 输出两者的乘积 FFT讲解 这个讲解蛮好的 就是讲解里面贴的模板是错误的 struct cpx { double x,y; cpx(double _x= ...
- hdu 3549 Flow Problem 最大流问题 (模板题)
Flow Problem Time Limit: 5000/5000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)Tota ...
- HDU1402 A * B Problem Plus FFT
分析:网上别家的代码都分析的很好,我只是给我自己贴个代码,我是kuangbin的搬运工 一点想法:其实FFT就是快速求卷积罢了,当小数据的时候我们完全可以用母函数来做,比如那种硬币问题 FFT只是用来 ...
- HDU-1402 A * B Problem Plus FFT(快速傅立叶变化)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1402 一般的的大数乘法都是直接模拟乘法演算过程,复杂度O(n^2),对于这题来说会超时.乘法的过程基本 ...
- UOJ#34 FFT模板题
写完上一道题才意识到自己没有在博客里丢过FFT的模板-- 这道题就是裸的多项式乘法,可以FFT,可以NTT,也可以用Karasuba(好像有人这么写没有T),也可以各种其他分治乘法乱搞-- 所以我就直 ...
- [hdu3549]Flow Problem(最大流模板题)
解题关键:使用的挑战程序设计竞赛上的模板,第一道网络流题目,效率比较低,且用不习惯的vector来建图. 看到网上其他人说此题有重边,需要注意下,此问题只在邻接矩阵建图时会出问题,邻接表不会存在的,也 ...
随机推荐
- cache:annotation-driven" 的前缀 "cache" 未绑定
问题: Caused by: org.springframework.beans.factory.xml.XmlBeanDefinitionStoreException: Line 29 in XML ...
- 查看mysql支持的存储引擎
查看mysql支持的存储引擎 show engines\G;
- Python基础(1)_python介绍、简单运算符
Python执行一个程序分为三个阶段 阶段一:先启动python解释器 阶段二:python解释器把硬盘中的文件读入到内存中 阶段三:python解释器解释执行刚刚读入内存的代码 二.编程语言的分类: ...
- 扩展 Yii2 自带的日志组件
<?php /** * author : forecho <caizhenghai@gmail.com> * createTime : 2015/12/22 18:13 * desc ...
- iOS category 类别 和 extension 扩展
category 类别 又称为 分类 在ios项目开发中允许使用类别为现有的类添加新的方法,并不需要创建子类.通过类别我们可以动态地为现有的类添加新的方法,可以将类的定义模块化地布局到多个相关文件中 ...
- Storm 执行异常 java.lang.RuntimeException: java.nio.channels.UnresolvedAddressException 问题解决
最近写的 binlog2kafka storm job 上线在一个新的集群环境中(storm 0.9.0.1, kafka 0.8), storm job 运行时报出如下异常: java.lang.R ...
- 数据分析第二篇:matplotlib 常用的几个绘图方法
Matplotlib matplotlib是python的绘图库,使用它可以很方便的绘制出版质量级别的图形 matplotlib的基本功能 1.基本绘图 1.1 绘制坐标系中连续的线,设置线型/线宽/ ...
- css 网站素装 追忆过去
素装代码,以表哀悼等.以下为全站CSS代码. html { filter: grayscale(100%); -webkit-filter: grayscale(100%); -moz-filter: ...
- 分享知识-快乐自己:大数据(hadoop)环境搭建
大数据 hadoop 环境搭建: 一):大数据(hadoop)初始化环境搭建 二):大数据(hadoop)环境搭建 三):运行wordcount案例 四):揭秘HDFS 五):揭秘MapReduce ...
- POJ 2253 Frogger(warshall算法)
题意:湖中有很多石头,两只青蛙分别位于两块石头上.其中一只青蛙要经过一系列的跳跃,先跳到其他石头上,最后跳到另一只青蛙那里.目的是求出所有路径中最大变长的最小值(就是在到达目的地的路径中,找出青蛙需要 ...