c++大数、分数、模数运算实现模板

大数

#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);
    }
};

分数

#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;}
};

模数运算

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;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
模板C++中一种通用的编程技术,它允许我们定义一个模板类,在这个类中可以使用任意类型的数据。因此,我们可以使用类模板实现向量的运算。 首先,我们可以定义一个名为Vector的类模板,其中包含私有数据成员和公共成员函数。私有数据成员可以包括向量的元素以及向量的大小。公共成员函数则可以包括向量的初始化、复制、加法、减法、点乘和输出等操作。 在类模板中,我们可以使用模板参数来表示向量的元素类型。例如,使用typename T来表示元素类型。这样,在模板类中,我们可以使用T来声明向量的元素数组。 接下来,我们可以实现模板中的各个成员函数。例如,我们可以使用构造函数来初始化向量的大小,并使用析构函数来释放内存。我们还可以使用复制构造函数和赋值运算符重载函数来实现向量的复制操作。 在加法、减法和点乘运算中,我们可以使用循环语句遍历向量的元素,并进行相应的运算。最后,我们可以使用输出函数来显示向量的元素。 使用类模板实现向量运算的好处是,我们可以在运行时根据需要实例化类模板,并使用不同类型的数据来进行运算。这样,我们可以更加灵活地处理不同类型的向量操作。 综上所述,我们可以通过实现一个类模板实现向量的运算。这种方法可以使我们更加灵活地处理不同类型的向量,并实现各种向量运算的功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值