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的更多相关文章

  1. 1199 Problem B: 大小关系

    求有限集传递闭包的 Floyd Warshall 算法(矩阵实现) 其实就三重循环.zzuoj 1199 题 链接 http://acm.zzu.edu.cn:8000/problem.php?id= ...

  2. 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 ...

  3. C - NP-Hard Problem(二分图判定-染色法)

    C - NP-Hard Problem Crawling in process... Crawling failed Time Limit:2000MS     Memory Limit:262144 ...

  4. Time Consume Problem

    I joined the NodeJS online Course three weeks ago, but now I'm late about 2 weeks. I pay the codesch ...

  5. Programming Contest Problem Types

        Programming Contest Problem Types Hal Burch conducted an analysis over spring break of 1999 and ...

  6. hdu1032 Train Problem II (卡特兰数)

    题意: 给你一个数n,表示有n辆火车,编号从1到n,入站,问你有多少种出站的可能.    (题于文末) 知识点: ps:百度百科的卡特兰数讲的不错,注意看其参考的博客. 卡特兰数(Catalan):前 ...

  7. BZOJ2301: [HAOI2011]Problem b[莫比乌斯反演 容斥原理]【学习笔记】

    2301: [HAOI2011]Problem b Time Limit: 50 Sec  Memory Limit: 256 MBSubmit: 4032  Solved: 1817[Submit] ...

  8. [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 ...

  9. [LeetCode] The Skyline Problem 天际线问题

    A city's skyline is the outer contour of the silhouette formed by all the buildings in that city whe ...

  10. PHP curl报错“Problem (2) in the Chunked-Encoded data”解决方案

    $s = curl_init(); curl_setopt($s, CURLOPT_POST, true); curl_setopt($s, CURLOPT_POSTFIELDS, $queryStr ...

随机推荐

  1. C语言之冒泡排序

    冒泡排序: 1). 简介 其实就是把一个数组的元素,按照从小到大(从大到小)得顺序,重新排列起来,这种排序就叫冒泡排序 例: int nums[5] = {5,4,3,2,1}; //经过排序后 下标 ...

  2. C语言之算数运算符

    一 什么是算数运算符 算术运算符: +:  就是把两个数据相加,得到和 -:  就是把两个数据相减,得到差 *:  就是把两个数据相乘,得到积 /:  就是把两个数据相除,得到商 %:  就是把两个数 ...

  3. BootStrap的菜单的快速创建

    在bootstrap的3.0版本及以上时,菜单的创建有所改变. 现在,我们只需记住3个类 dropdown open dropdown-menu. 前两个是为ul 列表的父元素用的,最后一个是给ul ...

  4. xhtml头文件设置

    设置字符集编码: <head> <meta http-equiv="Content-Type" Content="text/html" cha ...

  5. JDK安装(CentOS/rpm方式)

    1. 用如下命令检验是否已经自带了OpenJDK java -version 如果打印如下,则表示安装了OpenJDK java version "1.6.0" OpenJDK R ...

  6. 【css2、css3】css改变select选择框的样式

    效果: 代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...

  7. web.xml讲解

    <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE web-app PUBLIC "- ...

  8. Zookeeper单机版安装(CentOS 7环境下)

    一.环境操作系统和软件版本介绍 1.环境操作系统为CentOS Linux release 7.2.1511 (Core) 可用cat /etc/redhat-release查询 2.软件版本 Zoo ...

  9. C++第二天

    今天学会了反码和补码: 1.正数的反码是本身,负数的反码是高位不变,其余位取反(这里的数是指二进制数) 2.补码是反码加一得到的 对于数据类型分为基本类型:整型,浮点型,字符型和布尔值类型,还有飞基本 ...

  10. MySQL之索引优化

    很多数据库系统性能不理想是因为系统没有经过整体优化,存在大量性能低下的SQL 语句.这类SQL语句性能不好的首要原因是缺乏高效的索引.没有索引除了导致语句本身运行速度慢外,更是导致大量的磁盘读写操作, ...