【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. 设计模式:装饰模式(decorate)

    还是那几句话: 学无止境,精益求精 十年河东,十年河西,莫欺少年穷 学历代表你的过去,能力代表你的现在,学习代表你的将来 废话不多说,直接进入正题: 今天学习了装饰模式,但是代码看不太懂,于是我将装饰 ...

  2. 【强化学习】python 实现 q-learning 例四(例二改写)

    将例二改写成面向对象模式,并加了环境! 不过更新环境的过程中,用到了清屏命令,play()的时候,会有点问题.learn()的时候可以勉强看到:P 0.效果图 1.完整代码 相对于例一,修改的地方: ...

  3. 新人入坑Redis必会的吐血总结

    新人入坑Redis必会的吐血总结 一.什么是Redis Redis是一个使用C语言开发的开源的高性能的key-value存储系统,我们可以把它近似理解为Java Map.简单来讲,Redis是一种NO ...

  4. 大话重构连载15:采用Mock技术完成测试

    第五次重构我们引入了数据库的设计,用户信息要从数据库中读取,问候语库存储在数据库中,并支持添加与更新.数据库的引入使自动化测试变得困难了,因为数据状态总是变化着的,而这种变化使得测试过程不能复现,这是 ...

  5. linux下日志文件error监控报警脚本分享

    即对日志文件中的error进行监控,当日志文件中出现error关键字时,即可报警!(grep -i error 不区分大小写进行搜索"error"关键字,但是会将包含error大小 ...

  6. python基础学习笔记(六)

    学到这里已经很不耐烦了,前面的数据结构什么的看起来都挺好,但还是没法用它们做什么实际的事. 基本语句的更多用法 使用逗号输出 >>> print 'age:',25 age: 25 ...

  7. L2-027. 名人堂与代金券

    链接:名人堂与代金券 在比赛中这题只得了2分,赛后发现原来strcmp函数并不是只返回-1,0,1三种,而是返回正数负数0 但是在我的电脑上一般就是返回前三种,只是用后面的三种更稳妥点 都怪我基础不扎 ...

  8. github链接与心得体会

    https://github.com/wangyuefang/test 第一次使用github,我觉得github是一个非常人性化的软件,使用起来很方便.而且可以把GitHub作为免费的远程仓库,如果 ...

  9. NoSuchBeanDefinitionException:No qualifying bean of type

    Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException ...

  10. 使用node去爬虫

    let http = require('http'); let https = require('https');//引入node的https服务. let cheerio = require('ch ...