1630:SuperGCD
时间限制: 1000 ms 内存限制: 524288 KB【题目描述】
来源:SDOI 2009
Sheng Bill 有着惊人的心算能力,甚至能用大脑计算出两个巨大的数的 GCD(最大公约数)!因此他经常和别人比赛计算 GCD。有一天 Sheng Bill 很嚣张地找到了你,并要求和你比赛,但是输给 Sheng Bill 岂不是很丢脸!所以你决定写一个程序来教训他。
【输入】
输入共两行,第一行一个数 A,第二行一个数 B。
【输出】
一行,表示 A 和 B 的最大公约数。
【输入样例】
12
54
【输出样例】
6
【提示】
数据范围与提示:
对于全部数据,0<A,B≤1010000。
sol:就是这道题的加强版,方法几乎一样,只是压4位过不去,要压八位,但是最后涉及到乘法需要long long,又会变慢,所以要记录要乘的 2 的个数,在最后统计答案的时候一个个乘进去,我复杂度非常劣
#include <bits/stdc++.h> using namespace std; typedef int ll; inline ll read() { ll s=0; bool f=0; char ch=' '; while(!isdigit(ch)) { f|=(ch=='-'); ch=getchar(); } while(isdigit(ch)) { s=(s<<3)+(s<<1)+(ch^48); ch=getchar(); } return (f)?(-s):(s); } #define R(x) x=read() inline void write(ll x) { if(x<0) { putchar('-'); x=-x; } if(x<10) { putchar(x+'0'); return; } write(x/10); putchar((x%10)+'0'); return; } #define W(x) write(x),putchar(' ') #define Wl(x) write(x),putchar(' ') inline void Read_S(char *S) { int Len=0; char ch=' '; while(!isdigit(ch)) { ch=getchar(); } while(ch=='0') { ch=getchar(); } while(isdigit(ch)) { S[++Len]=ch; ch=getchar(); } return; } const int N=10005; const int Base=100000000,Power=8; char SX[N],SY[N]; struct BigNum { int a[N]; BigNum() { memset(a,0,sizeof a); } BigNum(char *S) { memset(a,0,sizeof a); int i,bb,Pos=0,Len=strlen(S+1); a[0]=(Len-1)/Power+1; for(i=1;i<=Len;i++) { if((i-1)%Power==0) { Pos++; bb=1; } a[Pos]+=bb*(S[i]-'0'); bb*=10; } } inline void Print() { write(a[a[0]]); int i; for(i=a[0]-1;i>=1;i--) { if(a[i]<10000000) putchar('0'); if(a[i]<1000000) putchar('0'); if(a[i]<100000) putchar('0'); if(a[i]<10000) putchar('0'); if(a[i]<1000) putchar('0'); if(a[i]<100) putchar('0'); if(a[i]<10) putchar('0'); write(a[i]); } } #define P(x) x.Print(),putchar(' ') #define Pl(x) x.Print(),putchar(' ') }; BigNum X,Y; //BigNum Ans; inline bool operator<(const BigNum &p,const BigNum &q) { if(p.a[0]!=q.a[0]) return p.a[0]<q.a[0]; int i; for(i=p.a[0];i>=1;i--) if(p.a[i]!=q.a[i]) { return p.a[i]<q.a[i]; } return false; } inline bool operator==(const BigNum &p,const BigNum &q) { if(p.a[0]!=q.a[0]) return false; int i; for(i=p.a[0];i>=1;i--) if(p.a[i]!=q.a[i]) { return false; } return true; } inline BigNum operator-(const BigNum &p,const BigNum &q) { int i; BigNum ans=p; for(i=1;i<=q.a[0];i++) { ans.a[i]-=q.a[i]; if(ans.a[i]<0) { ans.a[i]+=Base; ans.a[i+1]--; } } while((!ans.a[ans.a[0]])&&ans.a[0]) ans.a[0]--; return ans; } inline BigNum operator*(const BigNum &p,const BigNum &q) { int i,j; BigNum ans; ans.a[0]=max(p.a[0],q.a[0]); for(i=1;i<=p.a[0];i++) { for(j=1;j<=q.a[0];j++) { ans.a[i+j-1]+=p.a[i]*q.a[j]; ans.a[i+j]+=ans.a[i+j-1]/Base; ans.a[i+j-1]%=Base; } } while(ans.a[ans.a[0]+1]) ans.a[0]++; while(!ans.a[ans.a[0]]) ans.a[0]--; return ans; } inline bool Judge_Ou(BigNum p) { if(!p.a[0]) return 1; return (p.a[1]&1)?0:1; } inline BigNum Div2(BigNum p) { BigNum ans; ans.a[0]=p.a[0]; int i; for(i=p.a[0];i>=1;i--) { ans.a[i]+=(p.a[i]>>1); if(p.a[i]&1) p.a[i-1]+=Base; } while(!ans.a[ans.a[0]]) ans.a[0]--; return ans; } inline BigNum Mul2(BigNum p) { BigNum ans; ans.a[0]=p.a[0]; int i; for(i=1;i<=p.a[0];i++) { p.a[i]<<=1; if(p.a[i]>Base) { ans.a[i+1]+=p.a[i]/Base; p.a[i]%=Base; } ans.a[i]+=p.a[i]; } while(ans.a[ans.a[0]+1]) ans.a[0]++; return ans; } int main() { int i; Read_S(SX); reverse(SX+1,SX+strlen(SX+1)+1); X=BigNum(SX); Read_S(SY); reverse(SY+1,SY+strlen(SY+1)+1); Y=BigNum(SY); // Ans.a[0]=Ans.a[1]=1; int Ges2=0; while(!(X==Y)) { // P(X); Pl(Y); bool BoX=Judge_Ou(X),BoY=Judge_Ou(Y); if(BoX) { if(BoY) { X=Div2(X); Y=Div2(Y); // Ans=Mul2(Ans); Ges2++; } else { X=Div2(X); } } else { if(BoY) { Y=Div2(Y); } else { BigNum p,q; if(X<Y) p=Y,q=X; else p=X,q=Y; X=p-q; Y=q; } } } for(i=1;i<=Ges2;i++) X=Mul2(X); // Ans=Ans*X; // Pl(Ans); Pl(X); return 0; }