【BZOJ1876】[SDOI2009]SuperGCD(数论,高精度)
【BZOJ1876】[SDOI2009]SuperGCD(数论,高精度)
题面
题解
那些说数论只会\(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(数论,高精度)的更多相关文章
- [BZOJ1876][SDOI2009]superGCD(高精度)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1876 分析: 以为辗转相减会TLE呢……但是好像没这个数据……就这么水过去了…… 辗转 ...
- bzoj 1876 [SDOI2009]SuperGCD(高精度+更相减损)
1876: [SDOI2009]SuperGCD Time Limit: 4 Sec Memory Limit: 64 MBSubmit: 2384 Solved: 806[Submit][Sta ...
- 【bzoj1876】[SDOI2009]SuperGCD(高精度)
题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=1876 一道简单的高精度+Stein算法(或者叫辗转相除法)求最大公约数板子题. md还 ...
- BZOJ1876:[SDOI2009]SuperGCD——C++高精度良心题解
http://www.lydsy.com/JudgeOnline/problem.php?id=1876 Description Sheng bill有着惊人的心算能力,甚至能用大脑计算出两个巨大的数 ...
- 洛谷 P2152 [SDOI2009]SuperGCD (高精度)
这道题直接写了我两个多小时-- 主要是写高精度的时候还存在着一些小毛病,调了很久 在输入这一块卡了很久. 然后注意这里用while的形式写,不然会炸 最后即使我已经是用的万进制了,但是交上去还是有两个 ...
- bzoj1876: [SDOI2009]SuperGCD
更相减损数. 上手就debug了3个小时,直接给我看哭了. 3个函数都写错了是什么感受? 乘2函数要从前往后乘,这样后面的数乘2进位以后不会干扰前面的数. 除2函数要从后往前除,这样前面的数借来的位不 ...
- bzoj千题计划288:bzoj1876: [SDOI2009]SuperGCD
http://www.lydsy.com/JudgeOnline/problem.php?id=1876 高精压位GCD 对于 GCD(a, b) a>b 若 a 为奇数,b 为偶数,GCD ...
- BZOJ1876 [SDOI2009]SuperGCD 【高精 + GCD优化】
题目 Sheng bill有着惊人的心算能力,甚至能用大脑计算出两个巨大的数的GCD(最大公约 数)!因此他经常和别人比 赛计算GCD.有一天Sheng bill很嚣张地找到了你,并要求和你比 赛,但 ...
- BZOJ 1876: [SDOI2009]SuperGCD( 更相减损 + 高精度 )
更相减损,要用高精度.... --------------------------------------------------------------- #include<cstdio> ...
随机推荐
- Ionic App之国际化(3) json数组的处理
接上一篇Ionic App之国际化(2) json数组的处理 之后,如何处理json数据长度的问题,目前的一个折中方法是翻译长度字段. 多语言文件内容: "MyLa": { &qu ...
- QT 小总结
遇到的问题: 1:在debug模式下可以顺利执行,但是换到release模式下没法执行了.会显示 exited with code 1 . 解决办法:把产生的release文件放到QT的bin库下,看 ...
- [译]Kubernetes 分布式应用部署和人脸识别 app 实例
原文地址:KUBERNETES DISTRIBUTED APPLICATION DEPLOYMENT WITH SAMPLE FACE RECOGNITION APP 原文作者:skarlso 译文出 ...
- Bash笔记
expect写法 /usr/bin/expect <<-EOF set timeout 3000 spawn ssh root@${server_ip} expect { "pa ...
- Html5前端笔记
获取Dpi 在 window.load中添加: (function(){ if (!window.screen.deviceXDPI){ var tmpNode = document.createEl ...
- cf166e 在四面体上寻找路线数 递推,取模
来源:codeforces E. Tetrahedron You are given a tetrahedron. Let's mark its vertices ...
- wordcount程序
wordcount程序算是相比于前几次作业来说比较难得一个作业了.进行了一次真的自己编写程序.WC程序实现了对txt文件中的数据的计数,算出程序中有多少单词.字符数以及行数.这次的程序编程是采用的C语 ...
- ☆C++学习心得
C++是我进大学的学的第一种编程语言,在高中的时候有电脑课,有教过部分的VB语言,所以其实对编程也并不是非常的陌生,刚开是上课也觉得感觉不难,都懂,没多少课后,恍了个神..居然听不懂了!老师经常让我们 ...
- Maven的课堂笔记1
1 什么是maven? Maven是一个跨平台的项目管理工具,主要用于基于java平台的项目构建,依赖管理. Clean compile test package install run ...
- 伪静态与重定向--RewriteBase
RewriteBase用于设置目录级重写的基准URL,即所有的重定向都是基于这个URL.内部重定向可能看不出效果,但是在外部重定向(使用R flag后),如果不手动指定 / 为根目录,那么就会去整个磁 ...