题意简述

求两个整数a,b的最大公约数0 < a , b ≤ 10 ^ 10000。

题解思路

如果 a % 2 == 0 && b % 2 == 0 gcd(a,b) = gcd(a / 2, b / 2) * 2

如果 a % 2 == 0 && b % 2 != 0 gcd(a,b) = gcd(a / 2, b);

如果 a % 2 != 0 && b % 2 == 0 gcd(a,b) = gcd(a, b / 2);

如果 a % 2 != 0 && b % 2 != 0 gcd(a,b) = gcd(a - b, b);

代码

#include <cstring>
#include <iostream>
using namespace std;
struct Number
{
int a[100000];
int c;
Number& operator=(const Number& rhs)
{
c = rhs.c;
for (register int i = 1; i <= c; ++i)
a[i] = rhs.a[i];
return *this;
}
}n1, n2, ans, xx;
char st[100000];
bool b1, b2;
void print(const Number &x)
{
if (!x.c) {cout << 0 << endl; return;}
for (register int i = x.c + 1; --i; ) cout << x.a[i];
cout << endl;
}
bool compare(const Number &x, const Number &y)
{
if (x.c != y.c) return x.c < y.c;
for (register int i = x.c + 1; --i; )
if (x.a[i] != y.a[i])
return x.a[i] < y.a[i];
return 0;
}
void _swap(Number &x, Number &y)
{
Number t;
t = x; x = y; y = t;
}
void div(Number &x)
{
if (x.a[x.c] == 1) x.a[x.c] = 0, x.a[--x.c] += 10;
for (register int i = x.c; i; --i)
if (x.a[i] & 1)
{
x.a[i] /= 2;
x.a[i - 1] += 10;
}
else x.a[i] /= 2;
}
void mul(Number &x, const Number &y)
{
Number c;
memset(c.a, 0, sizeof c.a);
c.c = x.c + y.c - 1;
for (register int i = 1; i <= x.c; ++i)
for (register int j = 1; j <= y.c; ++j)
{
c.a[i + j - 1] += x.a[i] * y.a[j];
c.a[i + j] += c.a[i + j - 1] / 10;
c.a[i + j - 1] %= 10;
}
while (c.a[c.c + 1]) ++c.c;
_swap(c, x);
}
void sub(Number &x, const Number &y)
{
for (register int i = 1; i <= y.c; ++i)
{
x.a[i] -= y.a[i];
if (x.a[i] < 0)
{
x.a[i] += 10;
x.a[i + 1] -= 1;
}
}
int xx = y.c + 1;
while (x.a[xx] < 0) x.a[xx] += 10, x.a[++xx] -= 1;
while (!x.a[x.c] && x.c > 0) --x.c;
}
int main()
{
ans.a[++ans.c] = 1;
xx.a[++xx.c] = 2;
ios::sync_with_stdio(0);
cin >> st;
n1.c = strlen(st);
for (register int i = n1.c; i; --i)
n1.a[i] = st[n1.c - i] - '0';
cin >> st;
n2.c = strlen(st);
for (register int i = n2.c; i; --i)
n2.a[i] = st[n2.c - i] - '0';
if (compare(n1, n2)) _swap(n1, n2);
while (n2.c)
{
while (!(n1.a[1] & 1) && !(n2.a[1] & 1))
{
mul(ans, xx);
div(n1);
div(n2);
}
if (!(n1.a[1] & 1)) div(n1);
else if (!(n2.a[1] & 1)) div(n2);
else sub(n1, n2);
if (compare(n1, n2)) _swap(n1, n2);
}
mul(ans, n1);
print(ans);
}

洛谷 P2152 [SDOI2009]SuperGCD的更多相关文章

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

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

  2. 洛谷 2152 [SDOI2009]SuperGCD

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

  3. 洛谷P1972 [SDOI2009]HH的项链 题解

    [SDOI2009]HH的项链 题目背景 无 题目描述 HH 有一串由各种漂亮的贝壳组成的项链.HH 相信不同的贝壳会带来好运,所以每次散步完后,他都会随意取出一段贝壳,思考它们所表达的含义.HH 不 ...

  4. BZOJ1880或洛谷2149 [SDOI2009]Elaxia的路线

    BZOJ原题链接 洛谷原题链接 显然最长公共路径是最短路上的一条链. 我们可以把最短路经过的边看成有向边,那么组成的图就是一张\(DAG\),这样题目要求的即是两张\(DAG\)重合部分中的最长链. ...

  5. 洛谷P2148 [SDOI2009]E&D(博弈论)

    洛谷题目传送门 先安利蒟蒻仍在施工的博弈论总结 首先根据题目,石子被两两分组了,于是根据SG定理,我们只要求出每一组的SG值再全部异或起来就好啦. 把每一对数看成一个ICG,首先,我们尝试构造游戏的状 ...

  6. BZOJ1227或洛谷2154 [SDOI2009]虔诚的墓主人

    BZOJ原题链接 洛谷原题链接 又是扫描线,题解可看大佬的博客(太懒了不想打) #include<cstdio> #include<algorithm> using names ...

  7. BZOJ1228或洛谷2148 [SDOI2009]E&D

    BZOJ原题链接 洛谷原题链接 完全不会呀.. 写了这题才知道\(SG\)函数原来也能打表找规律... 题解请看大佬的博客 #include<cstdio> using namespace ...

  8. BZOJ1226或洛谷2157 [SDOI2009]学校食堂

    BZOJ原题链接 洛谷原题链接 注意到\(B[i]\)很小,考虑状压\(DP\). 设\(f[i][j][k]\)表示前\(i - 1\)个人已经拿到菜,第\(i\)个人及其后面\(7\)个人是否拿到 ...

  9. [洛谷P1972][SDOI2009]HH的项链

    题目大意:给你一串数字,多次询问区间内数字的种类数 题解:莫队 卡点:洛谷数据加强,开了个$O(2)$ C++ Code: #include <cstdio> #include <a ...

随机推荐

  1. idea-Java文件结构

    从项目目录来看 ,分级为project-module-package-classname.java 其中.java文件中包含至多一个publicclass.class文件和多个普通.class文件 . ...

  2. C#拼装JSON数组简易方法

    下面是我们想要拼接出来的JSON字符串,返回给前台 {"success":"true","msg":"","d ...

  3. 【基础算法-模拟-例题-金币】-C++

    原题链接:P2669 金币 这道题目完全是一道模拟题,只要按照题目中的加金币的算法和sum累加就可以很轻易得出最终答案. 说一下有一些点需要注意: 1.用i来计每天发的金币数,n来计已经拿了金币的天数 ...

  4. Java将文本文件压缩为tar.gz

    压缩 思路 准备输出流 FileOutputStream BufferedOutputStream TarOutputStream GZIPOutputStream 准备输入流 FileInputSt ...

  5. go 格式化 int,位数不够0补齐

    n := 32 sInt := fmt.Sprintf("%07d", n)

  6. 洛谷 P1463、POI2002、HAOI2007 反素数

    题意: 求最小的$x\in[1,N]$,使得$x$为$g(x)$最大的数 中最小的一个. 分析: 1.$x$不会有超过$10$个不同质因子.理由:$2 \times 3\times 5...\time ...

  7. RabbitMQ(二):RabbitMQ高级特性

    RabbitMQ是目前非常热门的一款消息中间件,不管是互联网大厂还是中小企业都在大量使用.作为一名合格的开发者,有必要了解一下相关知识,RabbitMQ(一)已经入门RabbitMQ,本文介绍Rabb ...

  8. python 2.7 - 3.5 升级之路 (二) : 语法与类库升级

    背景 在上一篇博文中,我们为升级python 2 -> 3已经做了一些准备.在这篇中,我们将针对语法与类库这两个方面进行讨论. 关于语法 1. print 在python3中, print 已经 ...

  9. java:选择排序法对数组排序

    最近想练一练Java的算法,然后碰到LeetCode上一道从排序数组删除重复项的小题,刚开始没看到是从排序数组中,就乱写,其实要是排序树组,就比乱序的感觉上好写多了.然后就想回顾下冒泡法对数组排序,凭 ...

  10. ViewPager取消切换动画

    /** * Created by apk2sf on 2017/12/2. * email: apk2sf@163.com * QQ:337081267 */ public class NoAnima ...