【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 }
View Code

1876: [SDOI2009]SuperGCD

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

Sample Output

6

HINT

对于20%的数据,0 < A , B ≤ 10 ^ 18。
对于100%的数据,0 < A , B ≤ 10 ^ 10000。

Source

[Submit][Status][Discuss]
posted @ 2015-06-15 21:01  Tunix  阅读(...)  评论(...编辑  收藏