• bzoj1876 SuperGCD


    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;
    }
  • 相关阅读:
    深浅拷贝的区别
    vue中动态加载组件
    一些工具软件
    echarts 自传作品入口
    Echarts progress 设置背景颜色
    Echarts柱状图,柱子设置不一样的渐变色
    .net 控制台学习笔记 一、控制台程序的异常捕获
    IdentityServer4实战:自定义用户名和密码校验
    IdentityServer4实战:Token 中返回用户属性
    IdentityServer4实战:持久化 Resource
  • 原文地址:https://www.cnblogs.com/ccz181078/p/5136516.html
Copyright © 2020-2023  润新知