大数

const int maxl = 25;
const int bitlen = 4;
char buffer[maxl * bitlen + 10];
const int MAXL = 10000;

LL tmp[bitlen * maxl];
LL q[bitlen * maxl];

struct Bignum
{
    int a[maxl];
    int sz;
    bool read()
    {
        memset(a, 0, sizeof(a));
        sz = 0;
        if (scanf("%s", buffer) != 1) return false;
        int n = strlen(buffer);
        int i;
        for (i = n - 1; i >= 0; i -= bitlen)
        {
            LL x = 0, y = 1;
            for (int j = i; j > i - bitlen && j >= 0; --j)
            {
                x += y*(buffer[j] - '0');
                y *= 10;
            }
            a[sz++] = x;
        }
        return true;
    }

    Bignum()
    {
        memset(a, 0, sizeof(a));
        sz = 0;
    }

    Bignum(LL x)
    {
        memset(a, 0, sizeof(a));
        sz = 0;
        if (x == 0) sz = 1;
        while (x != 0)
        {
            a[sz++] = x % MAXL;
            x /= MAXL;
        }
    }
    Bignum(const Bignum&bg)
    {
        sz = bg.sz;
        memset(a, 0, sizeof(a));
        for (int i = 0; i < sz; ++i) a[i] = bg.a[i];
    }

    int cmp(const Bignum&bg) const
    {
        if (sz>bg.sz) return 1;
        else if (sz < bg.sz) return -1;
        for (int i = sz-1; i >= 0; --i)
        if (a[i] < bg.a[i])  return -1;
        else if (a[i]>bg.a[i]) return 1;
        return 0;
    }

    bool operator<(const Bignum&bg) const    { return cmp(bg) < 0; }
    bool operator==(const Bignum&bg) const { return cmp(bg) == 0; }
    bool operator<=(const Bignum&bg) const { return cmp(bg) <= 0; }
    bool operator>(const Bignum&bg) const { return cmp(bg)>0; }
    bool operator>=(const Bignum&bg) const { return cmp(bg) >= 0; }
    bool operator!=(const Bignum&bg) const { return cmp(bg) != 0; }

    Bignum operator=(const Bignum&bg)
    {
        sz = bg.sz;
        memset(a, 0, sizeof(a));
        for (int i = 0; i < sz; ++i) a[i] = bg.a[i];
        return *this;
    }
    void add(const Bignum&bg)
    {
        sz = max(sz, bg.sz);
        for (int i = 0; i < sz; ++i)
        {
            a[i] += bg.a[i];
            a[i + 1] += a[i] / MAXL;
            a[i] %= MAXL;
        }
        while (a[sz] != 0) ++sz;
    }
    Bignum operator+(const Bignum&bg)
    {
        if (bg == 0) return *this;
        Bignum ret = *this;
        ret.add(bg);
        return ret;
    }


    void sub(const Bignum&small)
    {
        for (int i = 0; i < sz; ++i)
        {
            a[i] -= small.a[i];
            if (a[i] < 0)
            {
                int j = i + 1;
                a[i] += MAXL;
                while (--a[j]<0)
                {
                    a[j] += MAXL;
                    ++j;
                }
            }
        }
        while (sz>1 && a[sz - 1] == 0) --sz;
    }
    void mul(const Bignum&b)
    {
        memset(tmp,0,sizeof(tmp));
        for(int i=0;i<sz;++i) {
            for(int j=0;j<b.sz;++j) {
                tmp[i+j]+=a[i]*b.a[j];
                tmp[i+j+1]+=tmp[i+j]/MAXL;
                tmp[i+j]%=MAXL;
            }
        }
        sz+=b.sz;
        while(tmp[sz]>0) {
            tmp[sz+1]+=tmp[sz]/MAXL;
            tmp[sz]%=MAXL;
            ++sz;
        }
        while(sz>1&&tmp[sz-1]==0) --sz;
        for(int i=0;i<sz;++i) a[i]=tmp[i];
    }

    Bignum operator-(const Bignum&small)
    {
        if (small == 0) return *this;
        int cp = cmp(small);
        if (cp == 0) return 0;
        Bignum A = *this, B = small;
        A.sub(B);
        return A;
    }

    Bignum operator/(LL x)
    {
        Bignum ret = *this;
        LL y = 0;
        for (int i = sz - 1; i >= 0; --i)
        {
            y = y*MAXL + ret.a[i];
            ret.a[i] = y / x, y %= x;
        }
        while (ret.sz > 1 && ret.a[ret.sz - 1] == 0) --ret.sz;
        return ret;
    }

    LL operator%(LL x)
    {
        LL y = 0;
        for (int i = sz - 1; i >= 0; --i)
        {
            y = y*MAXL + a[i];
            if (y >= x)  y %= x;
        }
        return y;
    }

    Bignum operator*(const Bignum&bg)
    {
        Bignum ret=*this;
        ret.mul(bg);
        return ret;
    }


    Bignum pow(LL x)
    {
        Bignum ret = 1, base = *this;
        while (x)
        {
            if (x & 1) ret = ret*base;
            base = base*base;
            x >>= 1;
        }
        return ret;
    }
    Bignum operator*(LL x)
    {
        return *this*Bignum(x);
    }

    bool Try_sub(char *s,char *t,int lent,int lens)
    {
        if(lent>lens) return false;
        for(int i=0;i<lens;++i) q[i]=s[i];

        bool ok=true;
        for(int i=0;i<lens;++i) {
            s[i]-=t[i];
            if(s[i]>=0) continue;
            int j=i+1;
            s[i] += 10;
            while (j<lens && --s[j]<0)
            {
                s[j] += 10;
                ++j;
            }
            if(j>=lens) { ok=false; break; }

        }
        if(ok) return true;
        for(int i=0;i<lens;++i) s[i]=q[i];
        return false;
    }
    Bignum operator/(const Bignum&bg)
    {
        int cp=cmp(bg);
        if(cp==0) return 1;
        else if(cp<0) return 0;
        char * s= new char[bitlen*sz+5], *t=new char [bitlen*sz+5];
        char * ans= new char [bitlen*sz+5];
        int lens=0,lent=0;
        s[lens]=t[lent]=0;
        for(int i=0;i<sz;++i) {
            int x=a[i];
            for(int j=0;j<4;++j) {
                s[lens++]=x%10;
                s[lens]=0;
                x/=10;
            }
            x=bg.a[i];
            for(int j=0;j<4;++j) {
                t[lent++]=x%10;
                t[lent]=0;
                x/=10;
            }
        }
        while(lent>1 && t[lent-1]==0) --lent;
        while(lens>1 && s[lens-1]==0) --lens;
        for(int i=lent;i<lens;++i) t[i]=0;
        for(int i=lens-1;i>=0;--i) {
            ans[i]=0;
            while(Try_sub(s+i,t,lent,lens-i)) ++ans[i];
        }
        for(int i=lens;i<=lens+4;++i) ans[i]=0;
        Bignum ret;
        for(int i=0;i<lens;i+=4) {
            ret.a[i/4]=1000*ans[i+3]+100*ans[i+2]+10*ans[i+1]+ans[i];
        }
        ret.sz=sz;
        while(ret.sz>1 && ret.a[ret.sz-1]==0) --ret.sz;
        delete [] s; delete [] t; delete [] ans;
        return ret;
    }
    Bignum operator%(const Bignum&bg)
    {
        if (bg == 0) return 0;
        Bignum ret = *this;
        ret = (ret / bg)*bg;
        return *this - ret;
    }

    void output() const
    {
        printf("%d", a[sz - 1]);
        for (int i = sz - 2; i >= 0; --i) printf("%04d", a[i]);
        printf("\n");
    }
};




第二版:压9位的大数

typedef long long LL;
const int maxl = 50;
const int bitlen = 9;
char buffer[maxl * bitlen + 10];
const int MAXL = 1000000000; //10^9

LL tmp[bitlen * maxl];
LL q[bitlen * maxl];

typedef unsigned long long u_long;
struct Bignum
{
    int a[maxl];
    int sz;
    bool read();

    Bignum() { memset(a, 0, sizeof(a)); sz = 1; }
    Bignum(u_long x);
    Bignum(const Bignum&);
    int cmp(const Bignum&bg) const;

    bool operator<(const Bignum&bg) const    { return cmp(bg) < 0; }
    bool operator==(const Bignum&bg) const { return cmp(bg) == 0; }
    bool operator<=(const Bignum&bg) const { return cmp(bg) <= 0; }
    bool operator>(const Bignum&bg) const { return cmp(bg)>0; }
    bool operator>=(const Bignum&bg) const { return cmp(bg) >= 0; }
    bool operator!=(const Bignum&bg) const { return cmp(bg) != 0; }

    bool Try_sub(char *s,char *t,int lent,int lens);

    Bignum& operator = (const Bignum&bg);
    Bignum& operator += (const Bignum&bg);
    Bignum & operator -= (const Bignum& bg);
    Bignum& operator *= (const Bignum& bg);

    Bignum& operator /= (const Bignum& bg);
    Bignum& operator /= (int x);
    int operator % (int x);

    Bignum operator + (const Bignum&bg) const { return Bignum(*this) += bg; }
    Bignum operator / (const Bignum& bg) const { return Bignum(*this) /= bg; }
    Bignum operator * (const Bignum& bg) const { return Bignum(*this) *= bg; }
    Bignum operator - (const Bignum&bg) const { return Bignum(*this) -= bg; }
    Bignum operator%(const Bignum&bg) const { return *this - *this / bg * bg; }
    Bignum operator / (int x) const { return Bignum(*this) /= x; }


    Bignum pow(LL x);


    void output() const
    {
        printf("%d", a[sz - 1]);
        for (int i = sz - 2; i >= 0; --i) printf("%09d", a[i]);
        printf("\r");
    }
};

bool Bignum::read()
 {
    memset(a, 0, sizeof(a));
    sz = 0;
    if (scanf("%s", buffer) != 1) return false;
    int n = strlen(buffer);
    int i;
    for (i = n - 1; i >= 0; i -= bitlen)
    {
        u_long x = 0, y = 1;
        for (int j = i; j > i - bitlen && j >= 0; --j)
        {
            x += y * (buffer[j] - '0');
            y *= 10;
        }
        a[sz++] = x;
    }
    return true;
}

Bignum::Bignum(u_long x)
{
    memset(a, 0, sizeof(a));
    sz = 0;
    if (x == 0) sz = 1;
    while (x != 0)
    {
        a[sz++] = x % MAXL;
        x /= MAXL;
    }
}

Bignum::Bignum(const Bignum& bg)
{
    sz = bg.sz;
    memcpy(a,bg.a,sizeof(a));
}

int Bignum::cmp(const Bignum&bg) const
{
    if (sz>bg.sz) return 1;
    else if (sz < bg.sz) return -1;
    for (int i = sz-1; i >= 0; --i)
    if (a[i] < bg.a[i])  return -1;
    else if (a[i] > bg.a[i]) return 1;
    return 0;
}

Bignum& Bignum::operator=(const Bignum& bg)
 {
    sz = bg.sz;
    memcpy(a,bg.a,sizeof(a));
    return *this;
}

Bignum& Bignum::operator += (const Bignum& bg)
{
    sz = max(sz, bg.sz);
    for (int i = 0; i < sz; ++i)
    {
        a[i] += bg.a[i];
        a[i + 1] += a[i] / MAXL;
        a[i] %= MAXL;
    }
    while (a[sz] != 0) ++sz;
    return *this;
}

Bignum& Bignum::operator -= (const Bignum& bg)
{
    for (int i = 0; i < sz; ++i)
    {
        a[i] -= bg.a[i];
        if (a[i] < 0)
        {
            int j = i + 1;
            a[i] += MAXL;
            while (--a[j]<0)
            {
                a[j] += MAXL;
                ++j;
            }
        }
    }
    while (sz>1 && a[sz - 1] == 0) --sz;
    return *this;
}

Bignum& Bignum::operator*=(const Bignum& b)
 {
    memset(tmp,0,sizeof(tmp));
    u_long w = 0;
    for(int i=0;i<sz;++i) if (a[i]) {
        for(int j=0;j<b.sz;++j) if (b.a[j]) {
            int k = i + j;
            w = (u_long) a[i] * b.a[j];
            while (w > 0) {
                w += tmp[k];
                tmp[k++] = w % MAXL;
                w /= MAXL;
            }
        }
    }
    sz+=b.sz;
    w = 0;
    while(tmp[sz]>0) {
        w += (u_long) tmp[sz];
        tmp[sz] = w % MAXL;
        w /= MAXL;
        ++sz;
    }
    while(sz>1&&tmp[sz-1]==0) --sz;
    for(int i=0;i<sz;++i) a[i] = tmp[i];
    return *this;
}


Bignum& Bignum::operator /= (int x)
{
    u_long y = 0;
    for (int i = sz - 1; i >= 0; --i)
    {
        y = y * MAXL + a[i];
        a[i] = y / x, y %= x;
    }
    while (sz > 1 && a[sz - 1] == 0) --sz;
    return *this;
}

int Bignum::operator % (int x)
{
    u_long y = 0;
    for (int i = sz - 1; i >= 0; --i)
    {
        y = y*MAXL + a[i];
        if (y >= x)  y %= x;
    }
    return y;
}

Bignum Bignum::pow(LL x)
{
    Bignum ret = 1, base = *this;
    while (x)
    {
        if (x & 1) ret = ret * base;
        base = base * base;
        x >>= 1;
    }
    return ret;
}

bool Bignum::Try_sub(char * s,char * t,int lent,int lens)
 {
    if(lent>lens) return false;
    for(int i=0;i<lens;++i) q[i]=s[i];

    bool ok=true;
    for(int i=0;i<lens;++i) {
        s[i]-=t[i];
        if(s[i]>=0) continue;
        int j=i+1;
        s[i] += 10;
        while (j<lens && --s[j]<0)
        {
            s[j] += 10;
            ++j;
        }
        if(j>=lens) { ok=false; break; }

    }
    if(ok) return true;
    for(int i=0;i<lens;++i) s[i]=q[i];
    return false;
}

Bignum& Bignum::operator /= (const Bignum& bg)
{
    int cp=cmp(bg);
    if(cp==0) return *this = 1;
    else if(cp<0) return *this = 0;
    char * s= new char[bitlen*(sz+2)], *t=new char [bitlen*(sz+2)];
    char * ans= new char [bitlen*(sz+2)];
    int lens=0,lent=0;
    s[lens]=t[lent]=0;
    for(int i=0;i<sz;++i) {
        int x=a[i];
        for(int j=0;j<bitlen;++j) {
            s[lens++]=x%10;
            s[lens]=0;
            x/=10;
        }
        x=bg.a[i];
        for(int j=0;j<bitlen;++j) {
            t[lent++]=x%10;
            t[lent]=0;
            x/=10;
        }
    }
    while(lent>1 && t[lent-1]==0) --lent;
    while(lens>1 && s[lens-1]==0) --lens;
    for(int i=lent;i<lens;++i) t[i]=0;
    for(int i=lens-1;i>=0;--i) {
        ans[i]=0;
        while(Try_sub(s+i,t,lent,lens-i)) ++ans[i];
    }
    for(int i=lens;i<=lens+bitlen;++i) ans[i]=0;
    for(int i=0;i<lens;i+=bitlen) {
        u_long x = 1;
        a[i/bitlen] = 0;
        for(int j = 0; j < bitlen; ++j) {
            a[i/bitlen] += x * ans[j+i];
            x *= 10;
        }
    }
    while(sz>1 && a[sz-1]==0) --sz;
    delete [] s; delete [] t; delete [] ans;
    return *this;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值