#ySybttg060306. 1630:SuperGCD

1630:SuperGCD

No testdata at current.

1630:SuperGCD

题目描述

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

输入格式

输入共两行,第一行一个数 AA,第二行一个数 BB

输出格式

一行,表示 AABB 的最大公约数。

样例

样例输入 #1

12
54

样例输出 #1

6

样例解释 #1

gcd(12,54)=6\gcd(12,54) = 6

数据范围

对于全部数据,0<A,B10100000 < A,B \le 10^{10000}

时空限制

  • 时间限制:1000 ms
  • 内存限制:524288 KB

注意:本题中 A,BA,B 是超大整数(可达 1000010000 位十进制数),因此必须使用高精度计算最大公约数。可以使用二进制 GCD 算法(Stein算法),因为它只涉及减法和移位,避免了大数取模运算。

二进制 GCD 算法步骤(对于高精度数):

  1. 如果 A=BA = B,则 gcd(A,B)=A\gcd(A,B) = A
  2. 如果 AABB 都是偶数,则 gcd(A,B)=2gcd(A/2,B/2)\gcd(A,B) = 2 \cdot \gcd(A/2, B/2)
  3. 如果 AA 是偶数,BB 是奇数,则 gcd(A,B)=gcd(A/2,B)\gcd(A,B) = \gcd(A/2, B)
  4. 如果 AA 是奇数,BB 是偶数,则 gcd(A,B)=gcd(A,B/2)\gcd(A,B) = \gcd(A, B/2)
  5. 如果 AABB 都是奇数,则 gcd(A,B)=gcd(AB,min(A,B))\gcd(A,B) = \gcd(|A-B|, \min(A,B))

需要实现高精度数的以下操作:

  • 判断奇偶性:只需看最低位是否为偶数。
  • 除以 22:高精度右移一位(即除以 22 取整)。
  • 比较大小:高精度比较。
  • 减法:高精度减法。
  • 乘法(乘以 22):实际上我们不需要乘以 22,而是记录因子 22 的个数 cntcnt,最后将结果左移 cntcnt 位(即乘以 2cnt2^{cnt})。

算法流程:

  1. 初始化 cnt=0cnt = 0
  2. ABA \neq B 时:
    • 如果 AABB 都是偶数,则 A=A/2A = A/2B=B/2B = B/2cnt=cnt+1cnt = cnt + 1
    • 否则如果 AA 是偶数,则 A=A/2A = A/2
    • 否则如果 BB 是偶数,则 B=B/2B = B/2
    • 否则(都是奇数),如果 A>BA > B,则 A=ABA = A - B,否则 B=BAB = B - A
  3. 最后结果为 A×2cntA \times 2^{cnt}(或 B×2cntB \times 2^{cnt},因为此时 A=BA=B)。

由于 A,BA,B 可达 1000010000 位,减法操作可能使得数值减小较慢,但每次操作都会减少数的规模(除以 22 或减法),因此总的操作次数不会太多(大约 O(log(max(A,B)))O(\log(\max(A,B))) 次)。但高精度运算本身复杂度与位数相关,总时间复杂度可以接受。

注意:输入的数可能很大,需要用字符串读入,并转换为高精度表示(例如用数组存储十进制位,或存储二进制位)。为了方便除以 22,可以用十进制存储,除以 22 时从高位到低位逐位计算。也可以将数转换为二进制表示(大整数转二进制),然后直接进行二进制操作,但转换可能较复杂。

由于数据规模较大,需要仔细实现高精度运算,并注意优化常数。