3123 高精度练习之超大整数乘法 - Wikioi
题目描述 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;
先把单位根的几个性质搞懂,然后就基本上可以理解这个分治了(最好是自己手算一下......我就懒得说什么了,自己都不是很理解,代码还是抄别人的)
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的更多相关文章
- Code[VS] 3123 高精度练习之超大整数乘法
FFT 做 高精度乘法 #include <bits/stdc++.h> ); struct complex { double a, b; inline complex( , ) { a ...
- codevs 3123 高精度练习之超大整数乘法
fft. #include<iostream> #include<cstdio> #include<cstring> #include<complex> ...
- 【CodeVS 3123】高精度练习之超大整数乘法 &【BZOJ 2197】FFT快速傅立叶
第一次写法法塔,,,感到威力无穷啊 看了一上午算导就当我看懂了?PS:要是机房里能有个清净的看书环境就好了 FFT主要是用了巧妙的复数单位根,复数单位根在复平面上的对称性使得快速傅立叶变换的时间复杂度 ...
- c++ 超大整数除法 高精度除法
c++ 超大整数除法 高精度除法 解题思路 计算a/b,其中a为大整数,b为普通整数,商为c,余数为r. 根据手算除法的规则,上一步的余数记为r,则本次计算的被除数为t=r*10+被除数的本位数值a[ ...
- c++ 超长整数乘法 高精度乘法
c++ 超长整数乘法 高精度乘法 解题思路 参考加法和减法解题思路 乘法不是一位一位的按照手算的方式进行计算,而是用循环用一个数的某一位去乘另外一个数 打卡代码 #include<bits/st ...
- POJ 1001 解题报告 高精度大整数乘法模版
题目是POJ1001 Exponentiation 虽然是小数的幂 最终还是转化为大整数的乘法 这道题要考虑的边界情况比较多 做这道题的时候,我分析了 网上的两个解题报告,发现都有错误,说明OJ对于 ...
- poj2389-Bull Math(大整数乘法)
一,题意: 大整数乘法模板题二,思路: 1,模拟乘法(注意"逢十进一") 2,倒序输出(注意首位0不输出) 三,步骤: 如:555 x 35 = 19425 5 5 5 5 5 ...
- OpenJudge 2980 大整数乘法
链接地址:http://bailian.openjudge.cn/practice/2980/ 题目: 总时间限制: 1000ms 内存限制: 65536kB 描述 求两个不超过200位的非负整数的积 ...
- codevs 3119 高精度练习之大整数开根 (各种高精+压位)
/* codevs 3119 高精度练习之大整数开根 (各种高精+压位) 二分答案 然后高精判重 打了一个多小时..... 最后还超时了...压位就好了 测试点#1.in 结果:AC 内存使用量: 2 ...
随机推荐
- 【转】android 安卓APP获取手机设备信息和手机号码的代码示例
http://blog.csdn.net/changemyself/article/details/7421476 下面我从安卓开发的角度,简单写一下如何获取手机设备信息和手机号码 准备条件:一部安卓 ...
- CSS行高--line-height
遇到的问题:在css中,不理解line-height:1与line-height:1px的区别 发现的过程:最近在学做一个网站的过程中,设置两行文字之间的行高时需要用到line-height,发现了这 ...
- Git CMD - tag: Create, list, delete or verify a tag object signed with GPG
命令格式 git tag [-a | -s | -u <keyid>] [-f] [-m <msg> | -F <file>] <tagname> [& ...
- C#性能优化实践
性能主要指两个方面:内存消耗和执行速度.性能优化简而言之,就是在不影响系统运行正确性的前提下,使之运行地更快,完成特定功能所需的时间更短. 本文以.NET平台下的控件产品MultiRow为例,描述C# ...
- SQL Server监测查询性能
SQL Server提供了以下工具(SET选项)来支持查询的监测: IO统计 TIME统计 PROFILER统计 XML统计 1. IO统计 当这个选项开启的时,对一批查询中的每一个数据对象访问的查询 ...
- JQuery中操作表单和表格
一:表单应用 1.HTML中的表单大致由三部分组成 (1).表单便签:包含处理表单数据所用的服务端程序URL,以及数据提交到服务器的方法. (2).表单域:包含文本框.密码框.隐藏域.多行文本框.复选 ...
- 学习IT技术的技巧
怎样学习一个知识A? (1).为什么需要A? (*) (2).什么是A? (*) (3).怎么使用A[最简答的]? (*) (4).使用A时注意的问题? (*) (5).A的应用领域. (6) ...
- 利用google api生成二维码名片例子
二维条码/二维码可以分为堆叠式/行排式二维条码和矩阵式二维条码.堆叠式/行排式二维条码形态上是由多行短截的一维条码堆叠而成:矩阵式二维条码以矩阵的形式组成,在矩阵相应元素位置上用“点”表示二进制“1” ...
- 创建Mysql 序列
create table sequence( name ) not null primary key, current_value , increment , max_value BIGINT, -- ...
- Js 变量的作用域
变量的作用域 所有的变量作用域是指在哪里可用哪里不可用 局部作用域和全局作用域 在js中以函数来分割作用域 在函数里面就叫做局部作用域,在函数外面的就叫全局作用域 在函数里面如果省略var 关键字 那 ...