题目链接: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();
}