• [SDOI2009]SuperGCD


    【题面】:
    [SDOI2009]SuperGCD

    【思路】:
    毒瘤高精。。
    考这种题真不知道出题人怎么想的,高精就算了还要压八位。。我高精板子都挂了还是寻欢大神给我了个板子(qwq)

    这是一道裸(du)的(liu)(GCD),当你把一切运算符都重载之后,你就可以愉快地(coding)出来(gcd)then TLE

    你还需要这个:更相减损术

    可半者半之,不可半者,副置分母、子之数,以少减多,更相减损,求其等也。以等数约之。(orz)

    具体来说,就是(如果需要对分数进行约分,那么)可以折半的话,就折半(也就是用(2)来约分)。如果不可以折半的话,那么就比较分母和分子的大小,用大数减去小数,互相减来减去,一直到减数与差相等为止,用这个相等的数字来约分。

    或者用(Stein)算法也可,都是神仙(orz)

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    
    struct huge{
        #define N_huge 10000
        #define base 100000000
        static char s[N_huge*10];
        typedef long long value;
        value a[N_huge];int len;
        void clear(){len=1;a[len]=0;}
        huge(){clear();}
        huge(value x){*this=x;}
        huge(char s[]){this->str(s);}
        huge operator =(const huge &b){
            len=b.len;for (int i=1;i<=len;++i)a[i]=b.a[i]; return *this;
        }
        huge operator +(const huge &b){
            int L=len>b.len?len:b.len;huge tmp;
            for (int i=1;i<=L+1;++i)tmp.a[i]=0;
            for (int i=1;i<=L;++i){
                if (i>len)tmp.a[i]+=b.a[i];
                else if (i>b.len)tmp.a[i]+=a[i];
                else {
                    tmp.a[i]+=a[i]+b.a[i];
                    if (tmp.a[i]>=base){
                        tmp.a[i]-=base;++tmp.a[i+1];
                    }
                }
            }
            if (tmp.a[L+1])tmp.len=L+1;
                else tmp.len=L;
            return tmp;
        }
        huge operator -(huge b){
            int L=len>b.len?len:b.len;huge tmp;
            for (int i=1;i<=L+1;++i)tmp.a[i]=0;
            for (int i=1;i<=L;++i){
                if (i>b.len)b.a[i]=0;
                tmp.a[i]+=a[i]-b.a[i];
                if (tmp.a[i]<0){
                    tmp.a[i]+=base;--tmp.a[i+1];
                }
            }
            while (L>1&&!tmp.a[L])--L;
            tmp.len=L;
            return tmp;
        }
        huge operator *(const huge &b)const{
            int L=len+b.len;huge tmp;
            for (int i=1;i<=L;++i)tmp.a[i]=0;
            for (int i=1;i<=len;++i)
                for (int j=1;j<=b.len;++j){
                    tmp.a[i+j-1]+=a[i]*b.a[j];
                    if (tmp.a[i+j-1]>=base){
                        tmp.a[i+j]+=tmp.a[i+j-1]/base;
                        tmp.a[i+j-1]%=base;
                    }
                }
            tmp.len=len+b.len;
            while (tmp.len>1&&!tmp.a[tmp.len])--tmp.len;
            return tmp;
        }
        pair<huge,huge> divide(const huge &a,const huge &b){
            int L=a.len;huge c,d;
            for (int i=L;i;--i){
                c.a[i]=0;d=d*base;d.a[1]=a.a[i];
                //while (d>=b){d-=b;++c.a[i];}
                int l=0,r=base-1,mid;
                while (l<r){
                    mid=(l+r+1)>>1;
                    if (b*mid<=d)l=mid;
                        else r=mid-1;
                }
                c.a[i]=l;d-=b*l;
            }
            while (L>1&&!c.a[L])--L;c.len=L;
            return make_pair(c,d);
        }
        huge operator /(value x){
            value d=0;huge tmp;
            for (int i=len;i;--i){
                d=d*base+a[i];
                tmp.a[i]=d/x;d%=x;
            }
            tmp.len=len;
            while (tmp.len>1&&!tmp.a[tmp.len])--tmp.len;
            return tmp;
        }
        value operator %(value x){
            value d=0;
            for (int i=len;i;--i)d=(d*base+a[i])%x;
            return d;
        }
        huge operator /(const huge &b){return divide(*this,b).first;}
        huge operator %(const huge &b){return divide(*this,b).second;}
        huge &operator +=(const huge &b){*this=*this+b;return *this;}
        huge &operator -=(const huge &b){*this=*this-b;return *this;}
        huge &operator *=(const huge &b){*this=*this*b;return *this;}
        huge operator /=(const huge &b){*this=*this/b;return *this;}
        huge operator %=(const huge &b){*this=*this%b;return *this;}
        huge &operator ++(){huge T;T=1;*this=*this+T;return *this;}
        huge &operator --(){huge T;T=1;*this=*this-T;return *this;}
        huge operator ++(int){huge T,tmp=*this;T=1;*this=*this+T;return tmp;}
        huge operator --(int){huge T,tmp=*this;T=1;*this=*this-T;return tmp;}
        huge operator +(value x){huge T;T=x;return *this+T;}
        huge operator -(value x){huge T;T=x;return *this-T;}
        huge operator *(value x){huge T;T=x;return *this*T;}
        //huge operator /(value x){huge T;T=x;return *this/T;}
        //huge operator %(value x){huge T;T=x;return *this%T;}
        huge operator *=(value x){*this=*this*x;return *this;}
        huge operator +=(value x){*this=*this+x;return *this;}
        huge operator -=(value x){*this=*this-x;return *this;}
        huge operator /=(value x){*this=*this/x;return *this;}
        huge operator %=(value x){*this=*this%x;return *this;}
        bool operator ==(value x){huge T;T=x;return *this==T;}
        bool operator !=(value x){huge T;T=x;return *this!=T;}
        bool operator <=(value x){huge T;T=x;return *this<=T;}
        bool operator >=(value x){huge T;T=x;return *this>=T;}
        bool operator <(value x){huge T;T=x;return *this<T;}
        bool operator >(value x){huge T;T=x;return *this>T;}
        huge operator =(value x){
            len=0;
            while (x)a[++len]=x%base,x/=base;
            if (!len)a[++len]=0;
            return *this;
        }
        bool operator <(const huge &b){
            if (len<b.len)return 1;
            if (len>b.len)return 0;
            for (int i=len;i;--i){
                if (a[i]<b.a[i])return 1;
                if (a[i]>b.a[i])return 0;
            }
            return 0;
        }
        bool operator ==(const huge &b){
            if (len!=b.len)return 0;
            for (int i=len;i;--i)
                if (a[i]!=b.a[i])return 0;
            return 1;
        }
        bool operator !=(const huge &b){return !(*this==b);}
        bool operator >(const huge &b){return !(*this<b||*this==b);}
        bool operator <=(const huge &b){return (*this<b)||(*this==b);}
        bool operator >=(const huge &b){return (*this>b)||(*this==b);}
        void str(char s[]){
            int l=strlen(s);value x=0,y=1;len=0;
            for (int i=l-1;i>=0;--i){
                x=x+(s[i]-'0')*y;y*=10;
                if (y==base)a[++len]=x,x=0,y=1;
            }
            if (!len||x)a[++len]=x;
        }
        void read(){
            scanf("%s",s);this->str(s);
        }
        void print(){
            printf("%d",(int)a[len]);
            for (int i=len-1;i;--i){
                for (int j=base/10;j>=10;j/=10){
                    if (a[i]<j)printf("0");
                        else break;
                }
                printf("%d",(int)a[i]);
            }
            printf("
    ");
        }
    };char huge::s[N_huge*10];
    
    huge gcd(huge a,huge b){
        
        huge c;c.clear();
        c = 1;
        while(((a%2)==0)&&((b%2)==0)){
            a/=2;
            b/=2;
            c*=2;
        }
        while(a!=b){
            if(a>b)a-=b;
            else b-=a;
        }
        c*=a;
        return c;
    }
    
    huge a;
    huge b;
    huge ans;
    
    int main(){
        a.read();b.read();
        ans = gcd(a,b);
        ans.print();
    }
    
  • 相关阅读:
    Office 转 PDF & PDF 转 SWF Windows版
    Office 转 PDF & PDF 转 SWF Linux版
    MP4Box 编译 和相应命令
    CentOS VNC 安装与配置,方便进行运程桌面连接
    系统时钟&&硬件时钟
    IPtables中SNAT、DNAT和MASQUERADE的含义
    配置SNAT实现共享上网
    DNAT & SNAT
    linux应急操作
    linux-清理linux空间
  • 原文地址:https://www.cnblogs.com/lajioj/p/9562696.html
Copyright © 2020-2023  润新知