bzoj 1876: [SDOI2009]SuperGCD (高精度+gcd)

1876: [SDOI2009]SuperGCD

Time Limit: 4 Sec   Memory Limit: 64 MB
Submit: 3251   Solved: 1122
[ Submit][ Status][ Discuss]

Description

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

Input

共两行: 第一行:一个数A。 第二行:一个数B。

Output

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

Sample Input

12
54

Sample Output

6

HINT

对于20%的数据,0 < A , B ≤ 10 ^ 18。
对于100%的数据,0 < A , B ≤ 10 ^ 10000。

Source

[ Submit][ Status][ Discuss]

题解:高精度+gcd

刚开始写的方法TLE了,所以照着网上的姿势写的。。。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define N 100006
#define inf 100000000
#define mx 1252
using namespace std;
char s[N],s1[N];
struct data{
	int len,s[mx+10];
	data() {
		memset(s,0,sizeof(s));
	}
	int &operator [](int i) {
		return s[i];
	}
	void operator /=(int x){
		for (int i=mx;i>=1;i--) 
		 s[i-1]+=s[i]%x*inf,s[i]/=x;
	}
	void operator -=(data &b) {
		for (int i=1;i<mx;i++) 
		s[i]=s[i]-b[i]+(s[i-1]+inf)/inf-1,s[i-1]=(s[i-1]+inf)%inf;
	}
	data operator *=(int x){
		for (int i=1;i<mx;i++) 
		s[i]=s[i]*x+s[i-1]/inf,s[i-1]%=inf;
	}
	bool operator > (data &b) {
		for (int i=mx;i>=1;i--) 
			if (b[i]!=s[i]) return s[i]>b[i];
		return 0;
	}
	void print() {
		int p=mx;
		while (!s[p]&&p>0) p--;
		printf("%d",s[p--]);
		while (p) printf("%08d",s[p--]);
		putchar('\n');
	}
	bool iszero() {
		for (int i=1;i<mx;i++)
		 if (s[i]!=0) return 0;
		return 1;
	}
	void read() {
         char tp[10010]={'0','0','0','0','0','0','0','0'};         
		 scanf("%s",tp+8);
         int L=strlen(tp+1),p=1;
         while(L-8*p+1>0)             
		  sscanf(tp+L-8*p+++1,"%08d",&s[p]);
    }
}a1,b1;
data gcd(data a,data b)
{ 
    int g=0; bool x,y;
	while (!a.iszero()&&!b.iszero()) {
		x=!(a[1]&1); y=!(b[1]&1);
		if (x&&y) g++,a/=2,b/=2;
		else if (x||y) {
			if (x) a/=2; 
			if (y) b/=2;
		}
		else {
			if (a>b) a-=b;
			else b-=a;
		}
	}
	if (b>a) a=b;
	for (int i=0;i<g;i++) a*=2;
	a.print();
}
int main()
{
	freopen("a.in","r",stdin);
	freopen("my.out","w",stdout);
	a1.read(); b1.read();
	gcd(a1,b1);
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值