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 ...
随机推荐
- Java Concurrency - Concurrent Collections
Data structures are a basic element in programming. Almost every program uses one or more types of d ...
- Nhibernate3.3.3sp1基础搭建测试
实体类 using System; using System.Collections.Generic; using System.Linq; using System.Text; using Syst ...
- Android环境搭建的步骤
Android 环境搭建步骤 这里简单介绍一下学习Android之后如何搭建环境的问题 一. 在搭建环境之前,首先你要先下载Java JDK(根据系统位数选择下载是64位或32位的),Eclip ...
- android组件间共享数据的常用方法
使用Intent在激活组件的时候携带数据,以进行数据的传递 使用广播进行组件间数据的伟递 使用外部存储(sharedPreference,文件,数据库,网络)进行组件间数据共享 使用Static静态成 ...
- Windows Forms (一)
导读 1.什么是 Windows Forms 2.需要学Windows Forms 么? 3.如何手写一个简单的Windows Forms 程序 4.对上面程序的说明 5.Form 类与Control ...
- OC9_字符串的内存管理
// // main.m // OC9_字符串的内存管理 // // Created by zhangxueming on 15/6/18. // Copyright (c) 2015年 zhangx ...
- setTimeout、clearTimeout、setInterval,clearInterval ——小小计时器
先看下效果 话不多说上代码~ <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Typ ...
- MFC中获取指针的方法
1.获取应用程序指针 CMyApp* pApp=(CMyApp*)AfxGetApp(); 2.获取主框架指针 CWinApp 中的公有成员变量 m_pMainWnd 就是主框架的指针 CMainFr ...
- 《大话设计模式》学习笔记0:设计模式的原则 && UML类图
一.单一职责原则:就一个类而言,应该仅有一个引起它变化的原因. 如果一个类承担的职责过多,就等于把这些职责耦合在一起,一个职责的变化可能会削弱或者抑制这个类完成其他职责的能力.这种耦合会导致脆弱的设计 ...
- 非常出色的一款WinForm窗体重绘GUI类库源码
基本控件的演示 ScrollBar滚动条 各种圆形进度条 ProgressBar进度条 Mdi演示,仿谷歌浏览器 多种皮肤可供选择 一套专业级别的GUI控件,目前包含了窗体.进度条.滚动条以及MDI多 ...