数运算的一些模板

用过的一些模板
1.分数类的运算

#include <utility>
#include <algorithm>
using namespace std;
using namespace rel_ops;

template <class VAL = long long> class Frac {
public:
    VAL num,den;
    Frac(){}
    Frac(const VAL& x, const VAL& y = 1){
        den=__gcd(x,y);
        num=x/den,den=y/den;
        if(den<0) num=-num,den=-den;
    }
    bool operator <(const Frac& rhs) const {
        return num*rhs.den<rhs.num*den;
    }
    bool operator==(const Frac& rhs) const {
        return num==rhs.num && den==rhs.den;
    }
    Frac operator +(const Frac& rhs) const {
        return Frac(num*rhs.den+den*rhs.num,den*rhs.den);
    }
    Frac operator -(const Frac& rhs) const {
        return Frac(num*rhs.den-den*rhs.num,den*rhs.den);
    }
    Frac operator *(const Frac& rhs) const {
        return Frac(num*rhs.num,den*rhs.den);
    }
    Frac operator /(const Frac& rhs) const {
        return Frac(num*rhs.den,den*rhs.num);
    }
    Frac operator -() const {return Frac(-num,den);}
    Frac& operator +=(const Frac& rhs){return *this=*this+rhs;}
    Frac& operator -=(const Frac& rhs){return *this=*this-rhs;}
    Frac& operator *=(const Frac& rhs){return *this=*this*rhs;}
    Frac& operator /=(const Frac& rhs){return *this=*this/rhs;}
};

2.取膜运算

class Imp {
public:
    static const int MOD = 1000000007;
    typedef long long LL;
    int u;
    Imp(){};    // 以下所有函数的传入参数都必须在[0,MOD)之间
    Imp(int v):u(v){}   // 且运算符左侧类型必须是Imp
    operator int&(){return u;}
    operator const int&() const {return u;}
    Imp operator +(int v) const {return u+v<MOD?u+v:u+v-MOD;}
    Imp operator -(int v) const {return u<v?u-v+MOD:u-v;}
    Imp operator *(int v) const {return u*LL(v)%MOD;}
    Imp operator /(int v) const {return u*RR(v)%MOD;}
    Imp operator -() const {return u?MOD-u:0;}
    Imp& operator +=(int v){u+=u+v<MOD?v:v-MOD; return *this;}
    Imp& operator -=(int v){u-=u<v?v-MOD:v; return *this;}
    Imp& operator *=(int v){u=u*LL(v)%MOD; return *this;}
    Imp& operator /=(int v){u=u*RR(v)%MOD; return *this;}
    static LL RR(int x){
        return x>1?RR(MOD%x)*(MOD-MOD/x)%MOD:x;
    }
};

3.大数运算

#include <cstdio>
#include <string>
#include <cstring>
using namespace std;

class BigNum {
public:
    static const int MOD = 100000000;
    static const int BIT = 8, SIZE = 105;
    mutable int n,o;
    long long u[SIZE];
    BigNum(){}
    BigNum(const string& s){
        memset(this,0,sizeof(BigNum));
        int num=0,cnt=1;
        for(int i=s.size()-1;~i;i--){
            if(s[i]=='-') o^=1;
            if(s[i]>='0' && s[i]<='9'){
                num+=(s[i]-'0')*cnt;
                cnt*=10;
                if(cnt==MOD) u[n++]=num,num=0,cnt=1;
            }
        }
        if(!n || cnt>=10) u[n++]=num;
        if(!u[0] && n==1) o=0;
    }
    BigNum(long long x){
        memset(this,0,sizeof(BigNum));
        if(x<0) o=1,x=-x;
        do u[n++]=x%MOD; while(x/=MOD);
    }
    operator string() const {
        static char s[SIZE*BIT+10];
        char* c=s+sprintf(s,"%s%d",o?"-":"",int(u[n-1]));
        for(int i=n-2;~i;i--) c+=sprintf(c,"%0*d",BIT,int(u[i]));
        return s;
    }
    int operator [](int pos) const {
        static int e[BIT]={1};
        for(static int i=1;i<BIT;i++) e[i]=e[i-1]*10;
        return u[pos/BIT]/e[pos%BIT]%10;
    }
    int length() const {
        int ret=(n-1)*BIT+1;
        for(int x=u[n-1]/10;x;x/=10) ret++;
        return ret;
    }
    friend int cmp(const BigNum& l, const BigNum& r){
        if(l.o!=r.o) return (l.o?-1:1);
        if(l.n!=r.n) return (l.o?-1:1)*(l.n-r.n);
        for(int i=l.n-1;~i;i--) if(l.u[i]-r.u[i])
                return (l.o?-1:1)*(l.u[i]-r.u[i]);
        return 0;
    }
    // 运算符
    bool operator < (const BigNum& r) const {return cmp(*this,r)<0;}
    bool operator > (const BigNum& r) const {return cmp(*this,r)>0;}
    bool operator <=(const BigNum& r) const {return cmp(*this,r)<=0;}
    bool operator >=(const BigNum& r) const {return cmp(*this,r)>=0;}
    bool operator ==(const BigNum& r) const {return cmp(*this,r)==0;}
    bool operator !=(const BigNum& r) const {return cmp(*this,r)!=0;}
    BigNum operator +(const BigNum& r) const {return BigNum(*this)+=r;}
    BigNum operator -(const BigNum& r) const {return BigNum(*this)-=r;}
    BigNum operator *(int x) const {return BigNum(*this)*=x;}
    BigNum operator /(int x) const {return BigNum(*this)/=x;}
    BigNum& operator *=(const BigNum& r){return *this=*this*r;}
    BigNum& operator /=(const BigNum& r){return *this=*this/r;}
    BigNum& operator %=(const BigNum& r){return *this=*this%r;}
    BigNum& operator %=(int x){return *this=*this%x;}
    BigNum operator -() const {
        BigNum s=*this;
        if(s.u[0] || s.n>=2) s.o^=1;
        return s;
    }
    BigNum& operator +=(const BigNum& r){
        if(r.n==1 && !r.u[0]) return *this;
        if(r.o^o) return r.o^=1,*this-=r,r.o^=1,*this;
        if(r.n>n) n=r.n;
        for(int i=0;i<r.n;i++) u[i]+=r.u[i];
        for(int i=0;i<n;i++) if(u[i]>=MOD) u[i+1]++,u[i]-=MOD;
        if(u[n]) n++;
        return *this;
    }
    BigNum& operator -=(const BigNum& r){
        if(r.n==1 && !r.u[0]) return *this;
        if(r.o^o) return r.o^=1,*this+=r,r.o^=1,*this;
        if(cmp(*this,r)*(r.o?-1:1)<0){
            o^=1,n=r.n;
            for(int i=0;i<r.n;i++) u[i]=r.u[i]-u[i];
        }else{
            for(int i=0;i<r.n;i++) u[i]=u[i]-r.u[i];
        }
        for(int i=0;i<n;i++) if(u[i]<0) u[i+1]--,u[i]+=MOD;
        while(!u[n-1] && n>=2) --n;
        if(!u[0] && n==1) o=0;
        return *this;
    }
    BigNum operator *(const BigNum& r) const {
        BigNum s=0;
        if(!u[n-1] || !r.u[r.n-1]) return s;
        s.n=r.n+n-1;
        s.o=r.o^o;
        for(int i=0;i<n;i++) for(int j=0;j<r.n;j++)
            s.u[i+j]+=u[i]*r.u[j];
        for(int i=0;i<s.n;i++) if(s.u[i]>=MOD){
            s.u[i+1]+=s.u[i]/MOD;
            s.u[i]%=MOD;
            if(i==s.n-1) s.n++;
        }
        return s;
    }
    BigNum operator /(const BigNum& r) const {
        BigNum e[35],s=0,c=0;
        int m=0,ro=r.o,lo=o;
        r.o^=ro,o^=lo;
        for(e[m]=r;MOD>>++m;e[m]=e[m-1]+e[m-1]);
        for(int i=n-1;~i;i--){
            int tag=0;
            (s*=MOD)+=u[i];
            for(int x=m-1;~x;x--) if(s>=e[x]) s-=e[x],tag|=1<<x;
            (c*=MOD)+=tag;
        }
        r.o^=ro,o^=lo;
        if(c.u[0] || c.n>=2) c.o=r.o^o;
        return c;
    }
    BigNum operator %(const BigNum& r) const {
        BigNum e[35],s=0;
        int m=0,ro=r.o,lo=o;
        r.o^=ro,o^=lo;
        for(e[m]=r;MOD>>++m;e[m]=e[m-1]+e[m-1]);
        for(int i=n-1;~i;i--){
            (s*=MOD)+=u[i];
            for(int x=m-1;~x;x--) if(s>=e[x]) s-=e[x];
        }
        r.o^=ro,o^=lo;
        if(s.u[0] || s.n>=2) s.o=o;
        return s;
    }
    BigNum& operator *=(int x){
        if(!x) return *this=0;
        if(x<0) o^=1,x=-x;
        for(int i=0;i<n;i++) u[i]*=x;
        for(int i=0;i<n;i++) if(u[i]>=MOD){
            u[i+1]+=u[i]/MOD;
            u[i]%=MOD;
            if(i==n-1) n++;
        }
        if(!u[0] && n==1) o=0;
        return *this;
    }
    BigNum& operator /=(int x){
        if(x<0) o^=1,x=-x;
        for(int i=n-1;i;u[i--]/=x) u[i-1]+=u[i]%x*MOD;
        for(u[0]/=x;n>=2;n--) if(u[n-1]) break;
        if(!u[0] && n==1) o=0;
        return *this;
    }
    int operator %(int x) const {
        long long c=0;
        for(int i=n-1;~i;i--) c=(c*MOD+u[i])%x;
        return (1-o-o)*int(c);
    }
};
【问题描述】 封装一个模板组类Array,支持以下操作: 1. 构造函Array(int n),将组初始化为n个存储空间,建议使用vector; 2. 函input(int n),使用插入运算符<<读取据,最多读取n个元素,但不能超过组存储空间的上限; 3. 重载下标运算符,返回组的元素。 封装一个分类Fract,用来处理分功能和运算,能支持你的Array类使用。 1. 构造:传入两个参n和m,表示n/m;分在构造时立即转化成最简分。 提示:分化简有专门的算法,可自行调研 2. show()函:分输出为“a/b”或“-a/b”的形式,a、b都是无符号整。若a为0或b为1,只输出符号和分子,不输出“/”和分母。 3. 在分类上重载+=运算符,进行分的加法运算。 【输入形式】 输入为两部分,分别是一组实测试样例和一组分测试样例。 这两组测试样例都以正整n,且n小于1000,n表示需要输入n个实(或分)。 测试样例的第二行开始为n个实(或分)。其中每个分输入为两个整n、m,表示分n/m。 【输出形式】 第一部分输出一个实,是第一组测试样例之和;第二部分输出一个分,是第二组测试样例之和。 分输出时为最简形式,负号只会出现在最前面,若分母为1或分子为0,则只输出一个整,即分子部分,而没有“/”和分母部分。 【样例输入】 4 6 8 7 5 9 1 3 20 -15 80 150 -9 1 6 6 12 16 -33 -48 6 11 0 -10 【样例输出】 26 -17117/2640 25.00 下载源文件 得分25.00 最后一次提交时间:2021-06-08 21:49:12 共有测试据:5 平均占用内存:1.415K 平均运行时间:0.00648S 测试据 评判结果 测试据1 完全正确 测试据2 完全正确 测试据3 完全正确 测试据4 完全正确 测试据5 完全正确 详细 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值