[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
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 }