【BZOJ1876】[SDOI2009]SuperGCD(数论,高精度)

题面

BZOJ

洛谷

题解

那些说数论只会\(gcd\)的人呢?我现在连\(gcd\)都不会,谁来教教我啊?

显然\(gcd\)除了辗转相除之外还可以辗转相减,然而辗转相减对于这题而言显然还不够优秀。

我们这样子来做。

如果当前\(a,b\)都是\(2\)的倍数,那么我们就把\(2\)直接同时除掉,直接在\(gcd\)中乘上一个\(2\)。否则如果只有一个数是\(2\)的倍数,显然可以直接把这个\(2\)给除掉。

这样子可以大大减少复杂度,这个似乎叫做\(Stein\)算法。

给个小提醒,判断一个数是不是\(2\)的倍数的时候,用\(\&1\)判断比用\(\%2\)判断快了\(20\)倍。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define ll long long
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
const ll yw=1000000000000000000;
char ch[11000];
struct BigNum
{
ll s[800];int ws;
void output()
{
printf("%lld",s[ws]);
for(int i=ws-1;i;--i)
printf("%018lld",s[i]);
puts("");
}
void clear(){memset(s,0,sizeof(s));ws=0;}
void init(char *ch)
{
int l=strlen(ch+1);reverse(&ch[1],&ch[l+1]);
for(int i=1;i<=l;i+=18)
{
++ws;ll ss=1;
for(int j=0;j<18;++j)
if(i+j<=l)s[ws]+=(ch[i+j]-48)*ss,ss*=10;
else break;
}
}
void Div2()
{
for(int i=ws;i;--i)s[i-1]+=(s[i]&1)*yw,s[i]>>=1;s[0]=0;
while(!s[ws])--ws;
}
void Multi2()
{
for(int i=1;i<=ws;++i)s[i]=s[i]<<1;
for(int i=1;i<=ws;++i)s[i+1]+=s[i]/yw,s[i]%=yw;
while(s[ws+1])++ws,s[ws+1]+=s[ws]/yw,s[ws]%=yw;
}
}A,B,One,tmp;
BigNum operator-(BigNum a,BigNum b)
{
int ws=max(a.ws,1);
for(int i=1;i<=ws;++i)a.s[i]-=b.s[i];
for(int i=ws-1;i;--i)if(a.s[i]<0)a.s[i]+=yw,a.s[i+1]-=1;
while(!a.s[ws])--ws;
a.ws=ws;return a;
}
bool operator<(BigNum a,BigNum b)
{
if(a.ws!=b.ws)return a.ws<b.ws;
for(int i=a.ws;i;--i)
if(a.s[i]!=b.s[i])return a.s[i]<b.s[i];
return false;
}int main()
{
scanf("%s",ch+1);A.init(ch);
scanf("%s",ch+1);B.init(ch);
One.s[1]=One.ws=1;int two=0;
if(B<A)swap(A,B);
while(233)
{
if(A<One)break;
if(!(A.s[1]&1)&&!(B.s[1]&1))A.Div2(),B.Div2(),++two;
else if(!(A.s[1]&1))A.Div2();
else if(!(B.s[1]&1))B.Div2();
else B=B-A;if(B<A)swap(A,B);
}
while(two)B.Multi2(),--two;B.output();
return 0;
}

【BZOJ1876】[SDOI2009]SuperGCD(数论,高精度)的更多相关文章

  1. [BZOJ1876][SDOI2009]superGCD(高精度)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1876 分析: 以为辗转相减会TLE呢……但是好像没这个数据……就这么水过去了…… 辗转 ...

  2. bzoj 1876 [SDOI2009]SuperGCD(高精度+更相减损)

    1876: [SDOI2009]SuperGCD Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 2384  Solved: 806[Submit][Sta ...

  3. 【bzoj1876】[SDOI2009]SuperGCD(高精度)

    题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=1876 一道简单的高精度+Stein算法(或者叫辗转相除法)求最大公约数板子题. md还 ...

  4. BZOJ1876:[SDOI2009]SuperGCD——C++高精度良心题解

    http://www.lydsy.com/JudgeOnline/problem.php?id=1876 Description Sheng bill有着惊人的心算能力,甚至能用大脑计算出两个巨大的数 ...

  5. 洛谷 P2152 [SDOI2009]SuperGCD (高精度)

    这道题直接写了我两个多小时-- 主要是写高精度的时候还存在着一些小毛病,调了很久 在输入这一块卡了很久. 然后注意这里用while的形式写,不然会炸 最后即使我已经是用的万进制了,但是交上去还是有两个 ...

  6. bzoj1876: [SDOI2009]SuperGCD

    更相减损数. 上手就debug了3个小时,直接给我看哭了. 3个函数都写错了是什么感受? 乘2函数要从前往后乘,这样后面的数乘2进位以后不会干扰前面的数. 除2函数要从后往前除,这样前面的数借来的位不 ...

  7. bzoj千题计划288:bzoj1876: [SDOI2009]SuperGCD

    http://www.lydsy.com/JudgeOnline/problem.php?id=1876 高精压位GCD 对于  GCD(a, b)  a>b 若 a 为奇数,b 为偶数,GCD ...

  8. BZOJ1876 [SDOI2009]SuperGCD 【高精 + GCD优化】

    题目 Sheng bill有着惊人的心算能力,甚至能用大脑计算出两个巨大的数的GCD(最大公约 数)!因此他经常和别人比 赛计算GCD.有一天Sheng bill很嚣张地找到了你,并要求和你比 赛,但 ...

  9. BZOJ 1876: [SDOI2009]SuperGCD( 更相减损 + 高精度 )

    更相减损,要用高精度.... --------------------------------------------------------------- #include<cstdio> ...

随机推荐

  1. pandas:字段值插入数据表第一行的解决办法

    1. 问题描述 在对课程表进行数据抽取时,由于课表结构的原因,需要在原始表字段名作为第一行数据,并对原始字段名进行替换. 原始数据如下所示: 2. 解决办法 经思考,此问题可抽象为:在不影响原始数据的 ...

  2. Web应用实例:音频可视化

    准备 语言:TypeScript 工具:Visual Studio Code 演示:Audio Visualiazer 小明告诉我,他希望打开一个网页,立即听到他喜欢的音乐,如果有视觉特效就更棒了. ...

  3. ABP+AdminLTE+Bootstrap Table权限管理系统第七节--登录逻辑及几种abp封装的Javascript函数库

    返回总目录:ABP+AdminLTE+Bootstrap Table权限管理系统一期         简介 经过前几节,我们已经解决数据库,模型,DTO,控制器和注入等问题.那么再来看一下登录逻辑.这 ...

  4. 关于Prometheus运维实践项目

    关于Promethues运维实践项目 1. 什么是Prometheus运维实践项目 ​ 是什么 ​ Prometheus,普罗米修斯,是古希腊神话中为人间带来火种的神. ​ Prometheus运维实 ...

  5. Linux df du 命令

    df 命令 检查磁盘空间占用情况(并不能查看某个目录占用的磁盘大小). 命令格式:df [option] -h 以容易理解的格式(给人看的格式)输出文件系统分区使用情况,例如 10kB.10MB.10 ...

  6. Linux ip forward

    Linux 默认带有 ip forward 功能,只不过因为各种原因,默认的配置把该功能关闭了.本文通过 demo 来演示 Linux 的 ip forward 功能,具体场景为:开启 Linux 的 ...

  7. nginx通过https方式反向代理多实例tomcat

    案例说明:前面一层nginx+Keepalived部署的LB,后端两台web服务器部署了多实例的tomcat,通过https方式部署nginx反向代理tomcat请求.配置一如下: 1)LB层的ngi ...

  8. XenServer虚拟化环境安装记录

    Xenserver,思杰基于Xen的虚拟化服务器.Citrix XenServer是一种全面而易于管理的服务器虚拟化平台,基于强大的 Xen Hypervisor 程序之上.XenServer 是为了 ...

  9. Linux内核设计与实现 第十七章

    1. 设备类型 linux中主要由3种类型的设备,分别是: 设备类型 代表设备 特点 访问方式 块设备 硬盘,光盘 随机访问设备中的内容 一般都是把设备挂载为文件系统后再访问 字符设备 键盘,打印机 ...

  10. Linux环境C程序设计

    Linux基础 常用shell命令 命令 说明 命令 说明 man 查看联机帮助 ls 查看目录及文件列表 cp 复制目录或文件 mv 移动目录或文件 cd 改变文件或目录 rm 删除文件或目录 mk ...