【BZOJ】【1876】【SDOI2009】SuperGCD
高精度+GCD
唔……高精gcd其实可以这么算:
\[ GCD(a,b)= \begin{cases} a & b=0 \\ 2*GCD(\frac{a}{2},\frac{b}{2}) & a\mod 2=0,b \mod 2=0 \\ GCD(\frac{a}{2},b) & a\mod 2=0,b \mod 2=1 \\ GCD(a,\frac{b}{2}) & a\mod 2=1,b \mod 2=0 \\ GCD(b,a-b) & else \end{cases} \]
然而Windows下栈空间只有8M坑爹啊……本地根本不能跑大数据。。。然后一直挂……
只好把大部分操作都改成void类型,并且传引用,然后把gcd的过程改成对全局变量进行操作……并不传参数……
各种乱搞一气终于是过了这道模板题……sad
1 /************************************************************** 2 Problem: 1876 3 User: Tunix 4 Language: C++ 5 Result: Accepted 6 Time:1860 ms 7 Memory:1556 kb 8 ****************************************************************/ 9 10 //BZOJ 1876 11 #include<cstdio> 12 #include<cstring> 13 #include<cstdlib> 14 #include<iostream> 15 #include<algorithm> 16 #define rep(i,n) for(int i=0;i<n;++i) 17 #define F(i,j,n) for(int i=j;i<=n;++i) 18 #define D(i,j,n) for(int i=j;i>=n;--i) 19 #define pb push_back 20 using namespace std; 21 typedef long long LL; 22 inline int getint(){ 23 int r=1,v=0; char ch=getchar(); 24 for(;!isdigit(ch);ch=getchar()) if (ch=='-') r=-1; 25 for(; isdigit(ch);ch=getchar()) v=v*10-'0'+ch; 26 return r*v; 27 } 28 const int N=2010; 29 /*******************template********************/ 30 31 struct bint{ 32 int v[N]; 33 int l; 34 bint(){l=0; memset(v,0,sizeof v);} 35 int& operator [] (int x){return v[x];} 36 }a,b,r,t; 37 38 const int Limit=1000000000; 39 //const LL Limit=10000000000000000LL; 40 //1e16 41 void print(bint a){ 42 printf("%d",a[a.l]); 43 D(i,a.l-1,1) printf("%09d",a[i]); 44 puts(""); 45 } 46 bint operator - (bint a,bint b){ 47 F(i,1,a.l){ 48 a[i]-=b[i]; 49 if (a[i]<0) a[i]+=Limit,a[i+1]--; 50 } 51 while(a.l && a[a.l]==0) a.l--; 52 return a; 53 } 54 void div2(bint& a){ 55 F(i,1,a.l){ 56 if (a[i]&1) a[i-1]+=Limit/2; 57 a[i]>>=1; 58 } 59 while(a.l && a[a.l]==0) a.l--; 60 } 61 62 void mul2(bint &a){ 63 D(i,a.l,1){ 64 a[i]<<=1; 65 a[i+1]+=a[i]/Limit; 66 a[i]%=Limit; 67 } 68 while (a[a.l+1]>0) a.l++; 69 } 70 bool operator < (bint a,bint b){ 71 if (a.l!=b.l) return a.l<b.l; 72 D(i,a.l,1){ 73 if (a[i]!=b[i]) return a[i]<b[i]; 74 } 75 return 0; 76 } 77 void gcd(){ 78 if (b.l==0){ 79 r=a; return; 80 } 81 if (!(a[1]&1) && !(b[1]&1)){ 82 div2(a),div2(b); gcd(); mul2(r); return; 83 } 84 if (!(a[1]&1) && (b[1]&1)){ 85 div2(a); gcd(); return; 86 } 87 if ((a[1]&1) && !(b[1]&1)){ 88 div2(b); gcd(); return; 89 } 90 if (a<b) swap(a,b); 91 t=b; b=a-b; a=t; 92 gcd(); 93 } 94 char s1[20000],s2[20000]; 95 96 int main(){ 97 #ifndef ONLINE_JUDGE 98 freopen("1876.in","r",stdin); 99 freopen("1876.out","w",stdout); 100 #endif 101 scanf("%s%s",s1+1,s2+1); 102 int l1=strlen(s1+1),l2=strlen(s2+1); 103 a.l=l1/9+bool(l1%9); 104 b.l=l2/9+bool(l2%9); 105 F(i,1,a.l){ 106 int k1=max(1,l1-i*9+1),k2=l1-(i-1)*9; 107 F(j,k1,k2) a[i]=a[i]*10+s1[j]-'0'; 108 } 109 F(i,1,b.l){ 110 int k1=max(1,l2-i*9+1),k2=l2-(i-1)*9; 111 F(j,k1,k2) b[i]=b[i]*10+s2[j]-'0'; 112 } 113 gcd(); 114 print(r); 115 return 0; 116 }
1876: [SDOI2009]SuperGCD
Time Limit: 4 Sec Memory Limit: 64 MBSubmit: 1826 Solved: 589
[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。