[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来建图. 看到网上其他人说此题有重边,需要注意下,此问题只在邻接矩阵建图时会出问题,邻接表不会存在的,也 ...
随机推荐
- Linux基础系列:常用命令(7)_正则表达式
一.环境边量 每个用户登录shell需要执行的四个文件 /etc/profile /home/egon/.bashrc_profile /home/egon/.bashrc /etc/bashrc 非 ...
- LeetCode:盛最多水的容器【11】
LeetCode:盛最多水的容器[11] 题目描述 给定 n 个非负整数 a1,a2,...,an,每个数代表坐标中的一个点 (i, ai) .在坐标内画 n 条垂直线,垂直线 i 的两个端点分别为 ...
- Swift 枚举简单使用
//定义一个枚举 Direction 枚举字符名字 enum Direction{ case North case South case East case West }; enum Directio ...
- iOS __weak 和 __block 的使用探讨
在基本的开发中遇到 需要弱引用时候 我一般 用 weak 预防 死锁的时候 我会用 block 的确没出过大错 但是这样处理 的确有点囫囵 现在我想好好理解一下这两个修饰符 "bloc ...
- Android AbsoluteLayout绝对布局
绝对布局也叫坐标布局,指定元素的绝对位置,因为适应性很差,一般很少用到.可以使用RelativeLayout替代. 常用属性: android:layout_x --------组件x坐标 andro ...
- python 3 json 序列化
python 3 json 序列化 我们学习过用eval内置方法可以将一个字符串转成python对象,不过,eval方法是有局限性的,对于普通的数据类型,json.loads和eval都能用,但遇到特 ...
- curl 监控web
[root@rhel6 ~]# curl -I -s -w "%{http_code}\n" -o /dev/null http://127.0.0.1 [root@rhel6 ~ ...
- fzu 1476 矩形个数
注意点:精度 #include<iostream> using namespace std; typedef long long ll; int main() { int a,b; ll ...
- 最小生成树prim算法 POJ2031
#include<iostream> #include<algorithm> #include<string.h> #include<ctype.h> ...
- SpringCloud之客户端连接Eureka集群
客户端分别yml: ###服务启动端口号 server: port: 8002 ###服务名称(服务注册到eureka名称) spring: application: name: app-toov5- ...