洛谷 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);
}
原文地址:https://www.cnblogs.com/xuyixuan/p/9648105.html