码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj1876 SuperGCD

时间:2016-01-16 23:50:43      阅读:232      评论:0      收藏:0      [点我收藏+]

标签:

Description

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

Input

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

Output

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

Stein算法+高精度压位

首先不断约去A,B的公因数2直至A或B为奇数,记录约去2的次数k。

循环执行:{

 若A或B为偶数则不断约去2

 若A<B则交换A,B

 A-=B

 若A=0则输出B*2k,算法结束

}

#include<cstdio>
#include<cstring>
#define B 1000000000
const int B9=B-1;
char s[10010];
struct num{
    int a[1200];
    int l;
    num(){l=0;}
    inline void div2(){
        for(int i=l;i>0;i--){
            if(a[i]&1)a[i-1]+=B;
            a[i]>>=1;
        }
        a[0]>>=1;
        while(l&&!a[l])--l;
    }
    inline void mut2(){
        for(int i=0;i<=l;i++)a[i]<<=1;
        for(int i=0;i<=l;i++)a[i+1]+=a[i]/B,a[i]%=B;
        if(a[l+1])l++;
    }
    void print(){
        printf("%d",a[l]);
        for(int i=l-1;i>=0;i--)printf("%09d",a[i]);
    }
}a1,b1;
inline bool operator<(num&a,num&b){
    for(int i=a.l<b.l?b.l:a.l;i>=0;i--){
        if(a.a[i]<b.a[i])return true;
        if(a.a[i]>b.a[i])return false;
    }
    return false;
}
inline bool operator-=(num&a,num&b){
    a.a[0]+=1;
    for(int i=a.l;i>=0;i--)a.a[i]+=B9-b.a[i];
    for(int i=0;i<a.l;i++)a.a[i+1]+=a.a[i]/B,a.a[i]%=B;
    a.a[a.l]%=B;
    while(a.l&&!a.a[a.l])--a.l;
}
num*a=&a1,*b=&b1,*c;
int t2=0,l;
int p10[]={1,10,100,1000,10000,100000,1000000,10000000,100000000};
int main(){
    scanf("%s",s);
    l=strlen(s)-1;
    for(int i=0;i<=l;i++)a->a[(l-i)/9]+=p10[(l-i)%9]*(s[i]-0);
    a->l=l/9;
    if(a->a[a->l+1])a->l++;
    scanf("%s",s);
    l=strlen(s)-1;
    for(int i=0;i<=l;i++)b->a[(l-i)/9]+=p10[(l-i)%9]*(s[i]-0);
    b->l=l/9;
    if(b->a[b->l+1])b->l++;
    while(!(a->a[0]&1)&&!(b->a[0]&1)){
        t2++;
        a->div2();
        b->div2();
    }
    do{
        while(!(a->a[0]&1))a->div2();
        while(!(b->a[0]&1))b->div2();
        if(*a<*b)c=a,a=b,b=c;
        *a-=*b;
    }while(a->l!=0||a->a[0]!=0);
    while(t2--)b->mut2();
    b->print();
    return 0;
}

 

bzoj1876 SuperGCD

标签:

原文地址:http://www.cnblogs.com/ccz181078/p/5136516.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!