[SDOI2009]SuperGCD 高精度GCD

Description

Sheng bill有着惊人的心算能力，甚至能用大脑计算出两个巨大的数的GCD（最大公约 数）！因此他经常和别人比

Input

0 < A , B ≤ 10 ^ 10000。

12
54

Sample Output

6
solution

1.

a=a-b*(lena-lenb-1)  (具体实现 只需要标记一下，见代码)
2.

3.

  1 #include<cstdio>
2 #include<cstring>
3 #include<iostream>
4 #define mem(a,b) memset(a,b,sizeof(a))
5 #define ll long long
6 using namespace std;
7 const int Maxn=10066;
8
9 int comp;
10
11 struct bign
12 {
13     int s[Maxn],len;
14     bign(){len=1;mem(s,0);}
15     __attribute__((optimize("-O3"))) inline bign operator * (const int &c) const
16     {
17         bign now=*this,temp;
18         temp.len=now.len+15;
19         int x;
20         for(int i=1;i<=temp.len;++i)
21         {
22             temp.s[i]+=now.s[i]*c;
23             temp.s[i+1]+=temp.s[i]/10;
24             temp.s[i]%=10;
25         }
26         while(temp.s[temp.len]==0&&temp.len>1)
27           --temp.len;
28         return temp;
29     }
30     __attribute__((optimize("-O3"))) inline bign operator - (const bign &c) const//取地址会变快...
31     {
32         bign now=*this;
33         int q1=(now.len>c.len?now.len:c.len);
34         for(int i=1+comp;i<=q1;++i)
35         {
36             now.s[i]-=c.s[i-comp];
37             if(now.s[i]<0)
38             {
39                 --now.s[i+1];
40                 now.s[i]+=10;
41             }
42         }
43         while(now.len>1&&now.s[now.len]==0)
44           --now.len;
45         return now;
46     }
47     __attribute__((optimize("-O3"))) inline bign operator / (const int &c) const
48     {
49         bign now=*this,temp;
50         int x=0;
51         for(int i=now.len;i>=1;--i)
52         {
53             temp.s[i]=(x*10+now.s[i])/c;
54             x=(x*10+now.s[i])%c;
55         }
56         temp.len=now.len;
57         while(temp.len>1&&temp.s[temp.len]==0)
58           --temp.len;
59         return temp;
60     }
61 };
62
63 bign a,b;
64 char s[10066];
65 int ji;
66
68 {
69     scanf("%s",s);
70     int len=strlen(s);
71     a.len=len;
72     for(int i=0;i<len;++i)
73       a.s[len-i]=s[i]-'0';
74     scanf("%s",s);
75     len=strlen(s);
76     b.len=len;
77     for(int i=0;i<len;++i)
78       b.s[len-i]=s[i]-'0';
79 }
80
81 __attribute__((optimize("-O3"))) inline void out11(bign s)
82 {
83     for(int i=s.len;i>=1;--i)
84       printf("%d",s.s[i]);
85     printf("\n");
86 }
87
88 __attribute__((optimize("-O3"))) inline int com()
89 {
90     if(a.len>b.len)
91       return 3;
92     if(b.len>a.len)
93       return 1;
94     int flag;
95     for(int i=(a.len>b.len?a.len:b.len);i>=1;--i)
96     {
97         if(a.s[i]==b.s[i])
98           continue;
99         if(a.s[i]>b.s[i])
100           return 3;
101         if(a.s[i]<b.s[i])
102           return 1;
103     }
104     return 2;
105 }
106
107 __attribute__((optimize("-O3"))) inline void Gcd()
108 {
109     int flag;
110     while(1)
111     {
112         flag=com();
113         if(flag==2)
114           break;
115         while((a.s[1]&1)==0&&(b.s[1]&1)==0)
116         {
117             a=a/2;
118             b=b/2;
119             ++ji;
120         }
121         if(flag==1)
122         {
123             comp=((b.len-a.len-1)>0?(b.len-a.len-1):0);
124             b=b-a;
125         }
126         else
127         {
128             comp=((a.len-b.len-1)>0?(a.len-b.len-1):0);
129             a=a-b;
130         }
131     }
132 }
133
134 __attribute__((optimize("-O3"))) int main(){
135
136     //freopen("1.txt","r",stdin);
137
139     Gcd();
140     for(int i=1;i<=ji;++i)
141       a=a*2;
142     out11(a);
143 }
code

posted @ 2017-08-26 21:44  A_LEAF  阅读(382)  评论(0编辑  收藏  举报