[SDOI2009]SuperGCD 高精度GCD

Description

Sheng bill有着惊人的心算能力,甚至能用大脑计算出两个巨大的数的GCD(最大公约 数)!因此他经常和别人比
赛计算GCD。有一天Sheng bill很嚣张地找到了你,并要求和你比 赛,但是输给Sheng bill岂不是很丢脸!所以你
决定写一个程序来教训他。

Input

共两行: 第一行:一个数A。 第二行:一个数B。
0 < A , B ≤ 10 ^ 10000。

Output

一行,表示A和B的最大公约数。

Sample Input

12
54

Sample Output

6
solution

用更相减损术来计算GCD
优化:
1.
对于lena>lenb的情况
a=a-b*(lena-lenb-1)  (具体实现 只需要标记一下,见代码)
2.
把2都提出来  (但是好像并没有快)
3.
如果重载运算符,取地址可以变快...

这题最坑的是 phthon ...
 
 
  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 
 67 __attribute__((optimize("-O3"))) inline void read()
 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     
138     read();
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编辑  收藏  举报