山东济南彤昌机械科技有限公司 山东济南江鹏工贸游有限公司

bzoj 1876 [SDOI2009]SuperGCD(高精度+更相减损)

 

1876: [SDOI2009]SuperGCD

Time Limit: 4 Sec  Memory Limit: 64 MB
Submit: 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

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编辑  收藏  举报