BZOJ1876: [SDOI2009]SuperGCD

9 篇文章 0 订阅

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1876

题目简述:求Gcd(A,B)   0 < A , B ≤ 10 ^ 10000。


这尼玛..

如果还是Gcd(a,b)=Gcd(b,a%b) 那这就难写了。。


换种求法,数学书上的。更相减损术。

g是个计数器

若A%2==0 && B%2==0 则 g++,A/=2,B/=2

若A%2==0 && B%2!=0 则A/2

若A%2!=0  && B%2==0 则B/2

若A%2!=0 && B%2!=0 则 大-小

最后答案就是2^g*剩下的那个数。

。。这样好写些。


我写的高精度是神傻逼。。 O(1250)。。不想写进位退位。不记长度。。。。我都不想吐槽了。


#include <cstdio>
#include <cstring>
#include <algorithm>
#define rep(i,l,r) for (int i=l;i<=r;++i)
const int Mx=1252,MOD=100000000;
struct BIGN{
	int a[Mx+10];
	BIGN(){memset(a,0,sizeof a);}
	int &operator [](int i){return a[i];}
	void operator /=(int x){
		for (int i=Mx;i>=1;--i)
			a[i-1]+=a[i]%x*MOD,a[i]/=x;
		}
	void operator -=(BIGN &b){
		for (int i=1;i<Mx;++i)
			a[i]=a[i]-b[i]+(a[i-1]+MOD)/MOD -1,a[i-1]=(a[i-1]+MOD)%MOD;
		}
	void operator *=(int x){
		for (int i=1;i<Mx;++i)
			a[i]=a[i]*x+a[i-1]/MOD,a[i-1]%=MOD;
		}
	bool operator <(BIGN &b){
		for (int i=Mx;i>=1;--i)
			if (a[i]!=b[i]) return a[i]<b[i];
		return false;
		}
	bool iszero(){
		for (int i=1;i<Mx;++i) if (a[i]!=0) return false;
		return true;
		}
	void read(){
		char tp[10005]={'0','0','0','0','0','0','0','0'};
		scanf("%s",tp+8);
		int len=strlen(tp+1),p=1;
		while (len-8*p+1>0)
			sscanf(tp+len-8*p+++1,"%8d",&a[p]);
		}
	void print(){
		int p=Mx;
		while (!a[p]&&p>0) p--;
		printf("%d",a[p--]);
		while (p>0) printf("%08d",a[p--]);
		printf("\n");
		}
};
BIGN gcd(BIGN x,BIGN y){
	int g=0;bool x1,y1;
	while (!x.iszero() && !y.iszero()){
		x1=!(x[1]&1),y1=!(y[1]&1);
		if (x1 && y1){g++;x/=2,y/=2;}else
		if (x1 || y1){if (x1) x/=2;else y/=2;}else
		if (y<x) x-=y;else y-=x;
		}
	if (x<y) x=y;
	while (g--) x*=2;
	return x;
}
BIGN a,b;
int main(){
	a.read();
	b.read();
	gcd(a,b).print();
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值