[SDOI2009]SuperGCD
题目描述
Sheng bill有着惊人的心算能力,甚至能用大脑计算出两个巨大的数的GCD(最大公约 数)!因此他经常和别人比赛计算GCD。有一天Sheng bill很嚣张地找到了你,并要求和你比 赛,但是输给Sheng bill岂不是很丢脸!所以你决定写一个程序来教训他。
输入
共两行: 第一行:一个数A。 第二行:一个数B。
输出
一行,表示A和B的最大公约数。
样例输入
12
54
样例输出
6
提示
对于20%的数据,0 < A , B ≤ 10 ^ 18。
对于100%的数据,0 < A , B ≤ 10 ^ 10000。
#include <stdio.h> #include <cstring> #include <iostream> using std::swap; const int BASE = 100000000; const int MAXN = 10005; char s[MAXN]; int cnt; template<typename _t> inline _t read(){ _t x=0,f=1; char ch=getchar(); for(;!isdigit(ch);ch=getchar()) if(ch == '-') f=-f; for(;isdigit(ch);ch=getchar()) x = x*10+(ch^48); return x*f; } struct bignum{ long long a[MAXN],len; bignum(){memset(a,0,sizeof a);len = 0;} inline bool operator < (const bignum & b)const{ if(len != b.len) return len < b.len; for(int i = len;i>=1;i--) if(a[i] != b.a[i]) return a[i] < b.a[i]; return 0; } inline bool operator == (const bignum & b)const{ if(len != b.len) return 0; for(int i = len;i>=1;i--) if(a[i] != b.a[i]) return 0; return 1; } inline bool operator != (const bignum & b)const{return *this == b ? 0:1;} inline void operator = (const char *x){ register int tmp=strlen(x),t=1,k=0,js=0; for(int i=tmp-1;i>=0;--i){ k+=t*(x[i]-'0'),t*=10; if(t==BASE) t=1,a[++len]=k,k=0; } if(k) a[++len]=k; } inline bignum operator - (const bignum &c)const{ bignum ans; ans.len = len; bignum b = *this; for(register int i = 1;i<=c.len||i<=len;i++) { if(b.a[i] < c.a[i]) -- b.a[i+1] , b.a[i] += BASE; ans.a[i] = b.a[i] - c.a[i]; } while(ans.a[ans.len] == 0 && ans.len > 1) -- ans.len; return ans; } inline bignum operator / (const int x){ bignum ans = *this; for(int i = len;i>=1;i--) ans.a[i-1] += ans.a[i] % x * BASE,ans.a[i] /= x; while(!ans.a[ans.len] && ans.len > 1) -- ans.len; return ans; } inline bignum operator * (const int x){ bignum ans; ans.len = ++ len; for(int i = 1;i<=ans.len;i++) { ans.a[i] += a[i] * x; ans.a[i+1] += ans.a[i]/BASE; ans.a[i] %= BASE; } while(!ans.a[ans.len] && ans.len > 1) -- ans.len; return ans; } inline bool Judge(){return a[1] & 1;} inline void print(){printf("%lld",a[len]);for(register int i = len-1;i>=1;i--) printf("%08lld",a[i]);printf("\n");} inline void in(){scanf("%s",s);*this=s;} }a,b; inline bool Judge(){ if(!a.Judge() && !b.Judge()) {a = a / 2,b = b / 2,++ cnt;return 1;} if(!a.Judge()) {a = a / 2;return 1;} if(!b.Judge()) {b = b / 2;return 1;} return 0; } int main(){ a.in();b.in(); while(a != b) { while(Judge()); if(a == b) break; if(a<b) swap(a,b); a = a - b; } register int num1 = cnt / 25, num2 = cnt % 25 , full = 1<<25; while(num1) --num1,a = a * full; while(num2) --num2,a = a * 2; a.print(); }