【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. Linux 开启端口命令

    编者按 今天在配置Zookeeper集群的时候,碰到下面的问题: 这里说明是主机192.168.116.129:3888没有连通. 首先ping了一把,是通的,说明主机之间是连通的,然后再检查开放的端 ...

  2. EZ 2018 06 02 NOIP2018 模拟赛(十七)

    这次的比赛是真心比较狗,我TM的写了30min的树剖ZZ地直接memset超时了 话说我既然想到差分就应该去写差分的啊! 好了不过这次Rank还挺高的,终于要打进前10了当然是假的了. 好了下面开始讲 ...

  3. C# 全屏坐标及区域坐标获取。自定义光标及系统光标描边捕捉显示。

    最近手头工作比较轻松了一点就继续研究和完善之前的录屏软件,使用AForge最大的问题在于:最原始的只能够录全屏,而自定义的录屏需要更改非常多的细节:like follows: 1.需要支持区域化录屏: ...

  4. JAVA核心:内存、比较和Final

    1.java是如何管理内存的 java的内存管理就是对象的分配和释放问题.(其中包括两部分) 分配:内存的分配是由程序完成的,程序员需要通过关键字new为每个对象申请内存空间(基本类型除外),所有的对 ...

  5. 记一次用WPScan辅助渗透WordPress站点

    记一次用WPScan辅助渗透WordPress站点 一.什么是WPScan? WPScan 是一个扫描 WordPress 漏洞的黑盒子扫描器,它可以为所有 Web 开发人员扫描 WordPress ...

  6. mysql下批量清空某个库下的所有表(库不要删除,保留空库)

    总所周知,mysql下要想删除某个库下的某张表,只需要切换到该库下,执行语句"drop table tablename"即可删除!但若是该库下有成百上千张表,要是再这样一次次执行d ...

  7. Haproxy基础知识 -运维小结

    开源软件负载均衡器 现在常用的三大开源软件负载均衡器分别是Nginx.LVS.Haproxy. 在之前的文章中已经对比了这三个负载均衡软件, 下面根据自己的理解和使用经验, 再简单说下这三个负载均衡软 ...

  8. ELK基础架构解说-运维笔记

    一.ELK日志分析工具介绍1) Elasticsearch1.1)  Elasticsearch介绍ElasticSearch是一个基于Lucene的搜索服务器.它提供了一个分布式多用户能力的全文搜索 ...

  9. zookeeper安装(Linux)

    安装环境: Linux:centos6.4 Jdk:1.7以上版本 Zookeeper是java开发的可以运行在windows.linux环境.需要先安装jdk. 安装步骤: 第一步:安装jdk 第二 ...

  10. ADC转换的分辨率

    分辨率是指ADC能够分辨量化的最小信号的能力.分辨率用二进制位数表示.例如对一个10位的ADC,其所能分辨的最小量化电平为参考电平(满量程)的2的10次方分之一.也就是说分辨率越高,就能把满量程里的电 ...