A * B Problem Plus
A * B Problem Plus
题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1402
FFT
(FFT的详细证明参见算法导论第三十章)
一个多项式有两种表达方式:
1.系数表示法,系数表示的多项式相乘,时间复杂度为O(n^2);
2.点值表示法,点值表示的多项式相乘,时间复杂度为O(n).
简单的说,FFT能办到的就是将系数表示的多项式转化为点值表示,其时间复杂度为O(nlgn),而将点值表示的多项式转化为系数表示需要IFFT(FFT的逆运算),其形式与FFT相似,时间复杂度也为O(nlgn).
这道题需要用FFT将两个大数转化为点值表示,相乘后再用IFFT将点值表示转化回系数表示,总时间复杂度为O(nlgn).
代码如下:
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<iostream>
#define N 200005
using namespace std;
const double pi=acos(-1.0);
struct Complex{
double r,i;
Complex(double r=,double i=):r(r),i(i){};
Complex operator + (const Complex &rhs){
return Complex(r+rhs.r,i+rhs.i);
}
Complex operator - (const Complex &rhs){
return Complex(r-rhs.r,i-rhs.i);
}
Complex operator * (const Complex &rhs){
return Complex(r*rhs.r-i*rhs.i,i*rhs.r+r*rhs.i);
}
}a[N],b[N],c[N];
char s1[N],s2[N];
int ans[N],n1,n2,len;
inline void sincos(double theta,double &p0,double &p1){
p0=sin(theta);
p1=cos(theta);
}
void FFT(Complex P[], int n, int oper){
for(int i=,j=;i<n-;i++){
for(int s=n;j^=s>>=,~j&s;);
if(i<j)swap(P[i],P[j]);
}
Complex unit_p0;
for(int d=;(<<d)<n;d++){
int m=<<d,m2=m*;
double p0=pi/m*oper;
sincos(p0,unit_p0.i,unit_p0.r);
for(int i=;i<n;i+=m2){
Complex unit=;
for(int j=;j<m;j++){
Complex &P1=P[i+j+m],&P2=P[i+j];
Complex t=unit*P1;
P1=P2-t;
P2=P2+t;
unit=unit*unit_p0;
}
}
}
if(oper==-)for(int i=;i<len;i++)P[i].r/=len;
}
void Conv(Complex a[],Complex b[],int len){//求卷积
FFT(a,len,);//FFT
FFT(b,len,);//FFT
for(int i=;i<len;++i)c[i]=a[i]*b[i];
FFT(c,len,-);//IFFT
}
void init(char *s1,char *s2){
len=;
n1=strlen(s1),n2=strlen(s2);
while(len<*n1||len<*n2)len<<=;
int idx;
for(idx=;idx<n1;++idx){
a[idx].r=s1[n1--idx]-'';
a[idx].i=;
}
while(idx<len){
a[idx].r=a[idx].i=;
idx++;
}
for(idx=;idx<n2;++idx){
b[idx].r=s2[n2--idx]-'';
b[idx].i=;
}
while(idx<len){
b[idx].r=b[idx].i=;
idx++;
}
}
int main(void){
while(scanf("%s%s",s1,s2)==){
init(s1,s2);
Conv(a,b,len);
for(int i=;i<len+len;++i)ans[i]=;//93ms
//memset(ans,0,sizeof(ans));//140ms
int index;
for(index=;index<len||ans[index];++index){
ans[index]+=(c[index].r+0.5);
ans[index+]+=(ans[index]/);
ans[index]%=;
}
while(index>&&!ans[index])index--;
for(;index>=;--index)printf("%d",ans[index]);
printf("\n");
}
}
A * B Problem Plus的更多相关文章
- 1199 Problem B: 大小关系
求有限集传递闭包的 Floyd Warshall 算法(矩阵实现) 其实就三重循环.zzuoj 1199 题 链接 http://acm.zzu.edu.cn:8000/problem.php?id= ...
- No-args constructor for class X does not exist. Register an InstanceCreator with Gson for this type to fix this problem.
Gson解析JSON字符串时出现了下面的错误: No-args constructor for class X does not exist. Register an InstanceCreator ...
- C - NP-Hard Problem(二分图判定-染色法)
C - NP-Hard Problem Crawling in process... Crawling failed Time Limit:2000MS Memory Limit:262144 ...
- Time Consume Problem
I joined the NodeJS online Course three weeks ago, but now I'm late about 2 weeks. I pay the codesch ...
- Programming Contest Problem Types
Programming Contest Problem Types Hal Burch conducted an analysis over spring break of 1999 and ...
- hdu1032 Train Problem II (卡特兰数)
题意: 给你一个数n,表示有n辆火车,编号从1到n,入站,问你有多少种出站的可能. (题于文末) 知识点: ps:百度百科的卡特兰数讲的不错,注意看其参考的博客. 卡特兰数(Catalan):前 ...
- BZOJ2301: [HAOI2011]Problem b[莫比乌斯反演 容斥原理]【学习笔记】
2301: [HAOI2011]Problem b Time Limit: 50 Sec Memory Limit: 256 MBSubmit: 4032 Solved: 1817[Submit] ...
- [LeetCode] Water and Jug Problem 水罐问题
You are given two jugs with capacities x and y litres. There is an infinite amount of water supply a ...
- [LeetCode] The Skyline Problem 天际线问题
A city's skyline is the outer contour of the silhouette formed by all the buildings in that city whe ...
- PHP curl报错“Problem (2) in the Chunked-Encoded data”解决方案
$s = curl_init(); curl_setopt($s, CURLOPT_POST, true); curl_setopt($s, CURLOPT_POSTFIELDS, $queryStr ...
随机推荐
- Android自定义控件系列(一)—Button七十二变
转载请注明出处:http://www.cnblogs.com/landptf/p/6290791.html 忙了一段时间,终于有时间整理整理之前所用到的一些知识,分享给大家,希望给同学们有些帮助,同时 ...
- ipc 入侵步骤
第一步:建立IPC隧道net use \\10.56.204.186\IPC$ "密码" /user:"用户" 第二步:映射对方c盘到本地z盘net u ...
- 【BJG吐槽汇】第2期 - 我每周1-2次迟到都是因为你-->ios10!
本期槽点嘉宾:苹果系统 ios10 小吐我记得iphone是在2008年出的,当时我还在用诺基亚N70,对iphone是十分的陌生,想必大家也是,直到iphone4的时候,黄牛成群,饥饿营销,包括出i ...
- mysql添加mcafee 审计插件
插件源码地址https://github.com/mcafee/mysql-audit插件安装方法https://github.com/mcafee/mysql-audit/wiki/Installa ...
- 一些常用的操作MySQL数据库的sql语句
创建数据库:create database 数据库名; 删除数据库:drop datebase 数据库名; 查看数据库:show databases;(所有数据库) 使用数据库:use 数据库名;(之 ...
- 关于WIN7 家庭版 iis 部署问题
预装Win7家庭普通版系统的iis部署 必先升级为win7 预计10分钟因个人电脑而异 Win7家庭普通版系统的机器可免费升级为旗舰版.(WIN7任何低版本的系统 都可以升级到旗舰版) 开始的步骤: ...
- Kmplayer播放器 绿色免安装版 2016 中文版
软件名称: Kmplayer播放器 绿色免安装版 软件语言: 简体中文 授权方式: 免费软件 运行环境: Win 32位/64位 软件大小: 42.8MB 图片预览: 软件简介: Kmplayer播放 ...
- iOS GCD基础篇 - 同步、异步,并发、并行的理解
1.关于GCD - GCD全称是Grand Central Dispatch - GCD是苹果公司为多核的并行运算提出的解决方案 - GCD会自动利用更多的CPU内核(比如双核.四核) - GC ...
- EasyUI DataGrid 添加 Footer
做后台管理界面时,EasyUI 的 DataGrid 经常会被用到,有时候一些总的统计数据不合适放在数据表格里,需要单独显示,这时候就可以放在Footer中显示而不必另外布局. 该怎么给 DataGr ...
- linux内核之链表操作解析
本文只是对linux内核中的链表进行分析.内核版本是linux-2.6.32.63.文件在:linux内核/linux-2.6.32.63/include/linux/list.h.本文对list.h ...