洛谷 P2152 [SDOI2009]SuperGCD

题意简述

求两个整数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);
}

猜你喜欢

转载自www.cnblogs.com/xuyixuan/p/9648105.html