bzoj 1876 [SDOI2009]SuperGCD(高精度+更相减损)
1876: [SDOI2009]SuperGCD
Time Limit: 4 Sec Memory Limit: 64 MBSubmit: 2384 Solved: 806
[Submit][Status][Discuss]
Description
Sheng bill有着惊人的心算能力,甚至能用大脑计算出两个巨大的数的GCD(最大公约
数)!因此他经常和别人比赛计算GCD。有一天Sheng bill很嚣张地找到了你,并要求和你比
赛,但是输给Sheng bill岂不是很丢脸!所以你决定写一个程序来教训他。
Input
共两行:
第一行:一个数A。
第二行:一个数B。
Output
一行,表示A和B的最大公约数。
Sample Input
12
54
54
Sample Output
6
HINT
对于20%的数据,0 < A , B ≤ 10 ^ 18。
对于100%的数据,0 < A , B ≤ 10 ^ 10000。
Source
【思路】
除法不会写=-=
更相减损之术:
gcd(x,y)=2*gcd(x/2,y/2) --- x为偶数,y为偶数
gcd(x,y)=gcd(x/2,y) --- x为偶数,y为奇数
gcd(x,y)=gcd(x,y/2) ---x为奇数,y为偶数
gcd(x,y)=gcd(x,x-y) (x>y) ---x为奇数,y为奇数
高精度:压位,重载运算符写得太挫了导致各种TLE <_<,学了学别人的写法。
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 using namespace std; 6 7 const int mx = 1252; 8 const int rad = 1e8; 9 10 struct Bign { 11 int N[mx+10]; 12 Bign() {memset(N,0,sizeof(N));} 13 int &operator [](int i) {return N[i];} 14 void operator /= (int x) { 15 for(int i=mx;i>=1;i--) 16 N[i-1]+=N[i]%x*rad,N[i]/=x; 17 } 18 void operator -= (Bign& B) { 19 for(int i=1;i<mx;i++) 20 N[i]=N[i]-B[i]+(N[i-1]+rad)/rad -1,N[i-1]=(N[i-1]+rad)%rad; 21 } 22 Bign operator *= (int x) { 23 for(int i=1;i<mx;i++) 24 N[i]=N[i]*x+N[i-1]/rad,N[i-1]%=rad; 25 } 26 bool operator > (Bign& B) { 27 for(int i=mx;i>=1;i--) 28 if(N[i]!=B[i]) return N[i]>B[i]; 29 return 0; 30 } 31 void print() { 32 int p=mx; 33 while(!N[p]&&p>0) p--; 34 printf("%d",N[p--]); 35 while(p) printf("%08d",N[p--]); 36 putchar('\n'); 37 } 38 void read() { 39 char tp[10010]={'0','0','0','0','0','0','0','0'}; 40 scanf("%s",tp+8); 41 int L=strlen(tp+1),p=1; 42 while(L-8*p+1>0) 43 sscanf(tp+L-8*p+++1,"%8d",&N[p]); 44 } 45 bool iszero() { 46 for(int i=1;i<mx;i++) if(N[i]!=0) return 0; 47 return 1; 48 } 49 }; 50 51 Bign A,B; 52 53 int main() { 54 A.read();B.read(); 55 int g=0; bool x,y; 56 while(!A.iszero() && !B.iszero()) { 57 x=!(A[1]&1),y=!(B[1]&1); 58 if(x && y) { g++;A/=2;B/=2; } 59 else if((x)||(y)) { if(x)A/=2;else B/=2; } 60 else{ if(A>B) A-=B; else B-=A; } 61 } 62 if(B>A) A=B; 63 for(int i=0;i<g;i++) A*=2; 64 A.print(); 65 return 0; 66 }
posted on 2016-02-12 23:11 hahalidaxin 阅读(536) 评论(0) 编辑 收藏 举报