http://www.lydsy.com/JudgeOnline/problem.php?id=1876

Description

Sheng bill有着惊人的心算能力,甚至能用大脑计算出两个巨大的数的GCD(最大公约 数)!因此他经常和别人比
赛计算GCD。有一天Sheng bill很嚣张地找到了你,并要求和你比 赛,但是输给Sheng bill岂不是很丢脸!所以你
决定写一个程序来教训他。

Input

共两行: 第一行:一个数A。 第二行:一个数B。
0 < A , B ≤ 10 ^ 10000。

Output

一行,表示A和B的最大公约数。

Sample Input

12
54

Sample Output

6

——————————————————————————————————

如果你会写大整数除法,请跳过这个博客。

要做这道题:

1.我们要压位,对于压位默认看博客的人已经会了,如果不会请baidu。

2.我们需要三个gcd的应用

  1.gcd(a,b)=k*gcd(a/k,b/k)(a%k==0,b%k==0)

  2.gcd(a,b)=gcd(a/k,b)(a%k==0&&b%k!=0)

  3.gcd(a,b)=gcd(b,a-b)(a>b)

然后我们每次进行3操作的时候,用1和2操作来预先分离出来k,减少计算量。

这里取k=2,我们发现这种操作有着很妙的优化:

对于每次操作3,如果是:

  1.至少一个偶数,那么就1或2操作,至少减少了其中一个数一半的大小。

  2.无偶数,则3操作之后一定能变成1情况。

所以我们大概是能减少一半的运算量,这明显十分的妙!

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll big=1e9;
const int p=;
const int N=;
char s1[N],s2[N];
ll a[N],b[N];
int la=,lb=;
inline int pan(){
if(la>lb)return ;
if(la<lb)return ;
for(int i=la-;i>=;i--){
if(a[i]>b[i])return ;
if(a[i]<b[i])return ;
}
return ;
}
void diva(){
for(int i=la-;i>=;i--){
if(!(a[i]&))a[i]>>=;
else{
a[i-]+=big;
a[i]>>=;
}
}
  if(!a[la-])la--;
return;
}
void divb(){
for(int i=lb-;i>=;i--){
if(!(b[i]&))b[i]>>=;
else{
b[i-]+=big;
b[i]>>=;
}
}
if(!b[lb-])lb--;
return;
}
int change(char s[],ll n[]){
char temp[N];
int l=strlen(s),cur=;
while(l/p){
strncpy(temp,s+l-p,p);
n[cur++]=atoi(temp);
l-=p;
}
if(l){
memset(temp,,sizeof(temp));
strncpy(temp,s,l);
n[cur++]=atoi(temp);
}
return cur;
}
void init(){
scanf("%s%s",s1,s2);
la=change(s1,a);
lb=change(s2,b);
return;
}
int k_2=;
void gcd(){
while(){
int a_2=,b_2=;
while(!(a[]&)){diva();a_2++;}
while(!(b[]&)){divb();b_2++;}
k_2+=min(a_2,b_2);
int pi=pan();
if(pi==){
for(int i=;i<la;i++){
if(a[i]<b[i]){
a[i]+=big;
a[i+]--;
}
a[i]=a[i]-b[i];
}
for(int i=la-;i>=;i--){
if(a[i])break;
else la--;
}
}else if(pi==){
for(int i=;i<lb;i++){
if(b[i]<a[i]){
b[i]+=big;
b[i+]--;
}
b[i]=b[i]-a[i];
}
for(int i=lb-;i>=;i--){
if(b[i])break;
else lb--;
}
}else return;
}
return;
}
int main(){
init();
gcd();
for(int i=;i<=k_2;i++){
for(int j=;j<la;j++){
a[j]<<=;
}
for(int j=;j<la;j++){
if(a[j]>big){
a[j+]+=a[j]/big;
a[j]%=big;
if(j+>=la)la++;
}
}
}
printf("%lld",a[la-]);
for(int i=la-;i>=;i--){
printf("%0*lld",p,a[i]);
}
printf("\n");
return ;
}

BZOJ1876:[SDOI2009]SuperGCD——C++高精度良心题解的更多相关文章

  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 【高精 + GCD优化】

    题目 Sheng bill有着惊人的心算能力,甚至能用大脑计算出两个巨大的数的GCD(最大公约 数)!因此他经常和别人比 赛计算GCD.有一天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(数论,高精度)

    [BZOJ1876][SDOI2009]SuperGCD(数论,高精度) 题面 BZOJ 洛谷 题解 那些说数论只会\(gcd\)的人呢?我现在连\(gcd\)都不会,谁来教教我啊? 显然\(gcd\ ...

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

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

随机推荐

  1. 跟浩哥学自动化测试Selenium -- 浏览器的基本操作与元素定位(3)

    浏览器的基本操作与元素定位 通过上一章学习,我们已经学会了如何设置驱动路径,如何创建浏览器对象,如何打开一个网站,接下来我们要进行一些复杂的操作比如先打开百度首页,在打开博客园,网页后退,前进等等,甚 ...

  2. python函数参数默认值及重要警告

    最有用的形式是对一个或多个参数指定一个默认值.这样创建的函数,可以用比定义时允许的更少的参数调用,比如: def ask_ok(prompt, retries=4, reminder='Please ...

  3. post接口_ajax上传

    Action() { web_reg_save_param("find_msg", "LB=message\":\"", "RB= ...

  4. 栈和队列ADT -数据结构(C语言实现)

    数据结构与算法分析 栈模型 限制插入和删除只能在表的末端的表 表的末端叫做栈顶(top) 支持Push进栈和Pop入栈操作 //LIFO后进先出表 栈的实现 链表实现 类型声明 struct Node ...

  5. selenium常用操作方法

    Webdriver中比较常用的操作元素的方法: clear() 清除输入框的默认内容 send_keys("xxx") 在一个输入框里输入xx内容 ——如果输入中文,则需要在脚本开 ...

  6. 【Paper】Deep & Cross Network for Ad Click Predictions

    目录 背景 相关工作 主要贡献 核心思想 Embedding和Stacking层 交叉网络(Cross Network) 深度网络(Deep Network) 组合层(Combination Laye ...

  7. github 使用“git commit -m"命令时候出现的一个小问题

    git commit -m 使用问题 今天提交文件到github,步骤是: git add abc.py (abc.py是我当前随意写的一个文件名) git commit -m 'add codes ...

  8. solidity 智能合约操作

    合约编译 #!/usr/bin/env python # coding: utf8 import json import os # Solc Compiler from functools impor ...

  9. 采用c#实现功能1

    看了好多c#的菜鸟教程不如自己开始动手打代码,最终实现了功能一,参考了网上的wordcount代码发现无论是c++还是c#大部分采用的是哈希表的方法实现的,本来还想仅用循环实现遍历句子中的所有字符,即 ...

  10. LintCode-72.中序遍历和后序遍历树构造二叉树

    中序遍历和后序遍历树构造二叉树 根据中序遍历和后序遍历树构造二叉树 注意事项 你可以假设树中不存在相同数值的节点 样例 给出树的中序遍历: [1,2,3] 和后序遍历: [1,3,2] 返回如下的树: ...