题目描述 Description

给出两个正整数A和B,计算A*B的值。保证A和B的位数不超过100000位。

输入描述 Input Description

读入两个用空格隔开的正整数

输出描述 Output Description

输出A*B的值

样例输入 Sample Input

4 9

样例输出 Sample Output

36

数据范围及提示 Data Size & Hint

两个正整数的位数不超过100000位

什么都不说了,裸FFT

看了一天的算导,勉强看懂了怎么O(nlogn)求dft,求dft^(-1)就实在看不懂了,唉,只好记下结论

首先是理解系数表达和点值表达,因为点值表达乘法是O(n)的,所以我们要通过系数表达算出点值表达,相乘后再算出点值表达

这个是分治求的dft奇偶分成两个序列,分别求出这两个序列的dft然后通过下面的代码就可以O(n)合并这个两个dft了

 for i:= to n>>(t+)- do
begin
p:=i<<(t+)+s;
wt:=w[i<<t]*a[p+<<t];
tt[i]:=a[p]+wt;
tt[i+n>>(t+)]:=a[p]-wt;
end;

先把单位根的几个性质搞懂,然后就基本上可以理解这个分治了(最好是自己手算一下......我就懒得说什么了,自己都不是很理解,代码还是抄别人的)

zky神犇手动搬运算导FFT

pascal代码(我从这里抄的)

 const
s=;
type
cp=record
x,y:double;
end;
arr=array[.. shl ]of cp;
var
c:array[..]of int64;
a,b,w,tt:arr;
n,i,p:longint;
st:ansistring;
wt:cp; operator *(var a,b:cp)c:cp;
begin
c.x:=a.x*b.x-a.y*b.y;
c.y:=a.x*b.y+a.y*b.x;
end; operator +(var a,b:cp)c:cp;
begin
c.x:=a.x+b.x;
c.y:=a.y+b.y;
end; operator -(var a,b:cp)c:cp;
begin
c.x:=a.x-b.x;
c.y:=a.y-b.y;
end; procedure dft(var a:arr;s,t:longint);
begin
if n>>t= then exit;
dft(a,s,t+);
dft(a,s+<<t,t+);
for i:= to n>>(t+)- do
begin
p:=i<<(t+)+s;
wt:=w[i<<t]*a[p+<<t];
tt[i]:=a[p]+wt;
tt[i+n>>(t+)]:=a[p]-wt;
end;
for i:= to n>>t- do
a[i<<t+s]:=tt[i];
end; procedure get(var a:arr);
var
i,l,ll:longint;
c:char;
begin
read(c);
st:='';
while (ord(c)>=ord('')) and (ord(c)<=ord('')) do
begin
st:=st+c;
read(c);
end;
while length(st)mod s<> do
insert('',st,);
ll:=length(st)div s;
for l:= to ll do
val(copy(st,l*s-s+,s),a[ll-l].x);
while n>><l do
n:=n<<;
end; begin
n:=;
get(a);
get(b);
for i:= to n- do
w[i].x:=cos(pi**i/n);
for i:= to n- do
w[i].y:=sin(pi**i/n);
dft(a,,);
dft(b,,);
for i:= to n- do
a[i]:=a[i]*b[i];
for i:= to n- do
w[i].y:=-w[i].y;
dft(a,,);
for i:= to n- do
begin
c[i]:=c[i]+round(a[i].x/n);
c[i+]:=c[i] div ;
c[i]:=c[i] mod ;
end;
while (c[i]=) and (i>) do
dec(i);
for p:=i downto do
begin
str(c[p],st);
while (i<>p) and (length(st)<s) do
st:=''+st;
write(st);
end;
end.

又写了一遍233

 const
maxn=;
type
cp=record
x,y:double;
end;
arr=array[..maxn]of cp;
var
a,b,w,tt:arr;
n:longint;
s:ansistring;
c:array[..maxn]of longint; operator -(a,b:cp)c:cp;
begin
c.x:=a.x-b.x;
c.y:=a.y-b.y;
end; operator +(a,b:cp)c:cp;
begin
c.x:=a.x+b.x;
c.y:=a.y+b.y;
end; operator *(a,b:cp)c:cp;
begin
c.x:=a.x*b.x-a.y*b.y;
c.y:=a.x*b.y+a.y*b.x;
end; procedure get(var a:arr);
var
c:char;
i,len:longint;
begin
s:='';
read(c);
while c in[''..''] do
begin
s:=s+c;
read(c);
end;
len:=length(s);
for i:= to len do
a[len-i].x:=ord(s[i])-ord('');
while n<len<< do
n:=n<<;
end; procedure dft(var a:arr;s,t:longint);
var
i,p:longint;
wt:cp;
begin
if n>>t= then exit;
dft(a,s+<<t,t+);dft(a,s,t+);
for i:= to n>>t>>- do
begin
p:=i<<t<<+s;
wt:=w[i<<t]*a[p+<<t];
tt[i]:=a[p]+wt;
tt[i+n>>t>>]:=a[p]-wt;
end;
for i:= to n>>t- do
a[s+i<<t]:=tt[i];
end; procedure main;
var
i:longint;
begin
n:=;get(a);get(b);
for i:= to n- do w[i].x:=cos(pi**i/n);
for i:= to n- do w[i].y:=sin(pi**i/n);
dft(a,,);dft(b,,);
for i:= to n- do a[i]:=a[i]*b[i];
for i:= to n- do w[i].y:=-w[i].y;
dft(a,,);
for i:= to n- do c[i]:=round(a[i].x/n);
for i:= to n- do
begin
inc(c[i+],c[i]div );
c[i]:=c[i]mod ;
end;
i:=n-;
while (c[i]=) and (i>) do dec(i);
for i:=i downto do write(c[i]);
end; begin
main;
end.

3123 高精度练习之超大整数乘法 - Wikioi的更多相关文章

  1. Code[VS] 3123 高精度练习之超大整数乘法

    FFT 做 高精度乘法 #include <bits/stdc++.h> ); struct complex { double a, b; inline complex( , ) { a ...

  2. codevs 3123 高精度练习之超大整数乘法

    fft. #include<iostream> #include<cstdio> #include<cstring> #include<complex> ...

  3. 【CodeVS 3123】高精度练习之超大整数乘法 &【BZOJ 2197】FFT快速傅立叶

    第一次写法法塔,,,感到威力无穷啊 看了一上午算导就当我看懂了?PS:要是机房里能有个清净的看书环境就好了 FFT主要是用了巧妙的复数单位根,复数单位根在复平面上的对称性使得快速傅立叶变换的时间复杂度 ...

  4. c++ 超大整数除法 高精度除法

    c++ 超大整数除法 高精度除法 解题思路 计算a/b,其中a为大整数,b为普通整数,商为c,余数为r. 根据手算除法的规则,上一步的余数记为r,则本次计算的被除数为t=r*10+被除数的本位数值a[ ...

  5. c++ 超长整数乘法 高精度乘法

    c++ 超长整数乘法 高精度乘法 解题思路 参考加法和减法解题思路 乘法不是一位一位的按照手算的方式进行计算,而是用循环用一个数的某一位去乘另外一个数 打卡代码 #include<bits/st ...

  6. POJ 1001 解题报告 高精度大整数乘法模版

    题目是POJ1001 Exponentiation  虽然是小数的幂 最终还是转化为大整数的乘法 这道题要考虑的边界情况比较多 做这道题的时候,我分析了 网上的两个解题报告,发现都有错误,说明OJ对于 ...

  7. poj2389-Bull Math(大整数乘法)

    一,题意: 大整数乘法模板题二,思路: 1,模拟乘法(注意"逢十进一") 2,倒序输出(注意首位0不输出) 三,步骤: 如:555 x 35 = 19425  5 5 5  5 5 ...

  8. OpenJudge 2980 大整数乘法

    链接地址:http://bailian.openjudge.cn/practice/2980/ 题目: 总时间限制: 1000ms 内存限制: 65536kB 描述 求两个不超过200位的非负整数的积 ...

  9. codevs 3119 高精度练习之大整数开根 (各种高精+压位)

    /* codevs 3119 高精度练习之大整数开根 (各种高精+压位) 二分答案 然后高精判重 打了一个多小时..... 最后还超时了...压位就好了 测试点#1.in 结果:AC 内存使用量: 2 ...

随机推荐

  1. 【转】APP测试要点

    APP测试的时候,建议让开发打好包APK和IPA安装包,测试人员自己安装应用,进行测试.在测试过程中需要注意的测试点如下: 1.安装和卸载 ●应用是否可以在IOS不同系统版本或android不同系统版 ...

  2. Linux下配置文件的位置

    系统级的配置存放在 /etc 目录中.用户级的配置存放在用户的主目录 /home/user_login_name. SHELL 默认文件 /etc/bashrc – bash shell 的系统级默认 ...

  3. ActiveMQ(5.10.0) - Message Redelivery and DLQ Handling

    When messages expire on the ActiveMQ broker (they exceed their time-to-live, if set) or can’t be red ...

  4. Ehcache(2.9.x) - API Developer Guide, Using Explicit Locking

    About Explicit Locking Ehcache contains an implementation which provides for explicit locking, using ...

  5. 【转】Log4.NET mark

    C#通过log4net进行异常记录 C#中异常的记录也有一个模板,就是log4net.多的就不说了直接看怎么用的吧. 1.引用log4net.dll. 2.实现log4net的方法. public c ...

  6. UIViewSubviews多个views之间的关系

    #import "ViewController.h" @interface ViewController () @end @implementation ViewControlle ...

  7. Apache 使用密码文件验证用户

    使用文本文件作为密码文件 创建密码文件 需要使用htpasswd.exe文件来创建用户密码文件 语法: htpasswd -c '文件完整路径' 用户名 向一个用户密码文件中添加一个新用户 语法: h ...

  8. URL学习笔记

    不多说,先上代码,代码的注释写的已经挺详细的了 //URL:统一资源定位符,一个URL的对象,对应着互联网上的一个资源. //我们可以通过URL的对象调用其相应的方法,将此资源读取(即所谓的“下载”) ...

  9. CMakeLists实战解读--YouCompleteMe

    原文转载自:Ricky.K http://www.cnblogs.com/rickyk/p/3877238.html 个人一直有一个想法,就是想出一系列关于CMakeLists.txt国外经典例子的实 ...

  10. Js popup position which right under target item

    <div style="margin-left:600px;"> <div id="Span1" style="color:#eee ...