题目描述 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. ps扩大、缩小选区

    用"套索工具""魔棒工具"或者等工具将选区选出来,创建出一个需要处理的选区.   点击ps菜单栏中的"选择",在下拉菜单中选择"修 ...

  2. Slickflow.NET 开源工作流引擎基础介绍(四) -- 多数据库支持实现

    前言:引擎作为中间件集成到用户的项目里面去,针对用户的数据库类型,需要作出SQL部分的分别实现.引擎默认数据库为MS SQLSERVER,同时也支持ORACLE, MYSQL, KINGBASE等不同 ...

  3. django 学习-3 模板变量

    1.vim learn/home.html <!DOCTYPE html><html><head>        <title>{{title}}< ...

  4. CSS之颜色英文代码全集

    ColorHex在线颜色查询 <head> <title>CSS之颜色英文代码全集</title> <style type="text/css&qu ...

  5. CSS之鼠标经过字体光标形状的改变

    CSS中的cursor属性是规定要显示的光标的类型(形状). 参阅JavaScript正则表达式 default 默认光标(通常是一个箭头) auto 默认.浏览器设置的光标. crosshair 光 ...

  6. Java之绘制二次曲线

    前面已经介绍过绘制方法.这里不再赘述. 画一下草图来看看:灰色表示X值,红色表示Y值. 在这里要值得注意的是:当我们把它们的坐标在纸上画出来时,就会觉得“有问题”了,你看A(60,20,120,100 ...

  7. 实现iOS项目一款用swift实现的应用top源码

    Top 后台 Swift版本Ios 8 / iPhone 5S适配这边有个登陆,如果你们想测试的话,可以用这个账号, 账号:18868879362 密码:420562   源码下载: http://c ...

  8. 第二十九篇、UICollectionView瀑布流

    1.实现思路 >第一种方案:UIScrollView 镶嵌三个UITableView (不推荐使用) >第二种方案:UIScrollView 镶嵌UIImageView (需要解决循环利用 ...

  9. OC4_电子词典

    // // MyDictionary.h // OC4_电子词典 // // Created by zhangxueming on 15/6/15. // Copyright (c) 2015年 zh ...

  10. (转)IDG副总裁楼军:顶级VC青睐什么样的创业者

    学习能力是创业者的第一能力 创业者首先要有格局观和很强的学习能力. 具体什么意思?比如说去年IDG投了一个做C2C平台的海淘项目,创始人之前其实是帮他爱人做海淘代购.他爱人是一个代购买手,赚得还不错, ...