我的挫13大数模板

本文详细介绍了一种大数运算的实现方式,包括大数的加减乘除、比较及输入输出等功能,并提供了具体的应用实例,如解决HDU1002等编程题。

X

struct Bignum{
#define VV 10010
#define CONT int
#define WID 10000
    private:
        CONT bit[VV];
        int bitlen;
        bool flag;
    public:
        int getlen(){
            return bitlen;
        }
        CONT getpw(int x){
            switch (x)
            {
                case 0:return (CONT)1;
                case 1:return (CONT)10;
                case 2:return (CONT)100;
                case 3:return (CONT)1000;
                case 4:return (CONT)10000;
                case 5:return (CONT)100000;
                case 6:return (CONT)1000000;
                case 7:return (CONT)10000000;
                case 8:return (CONT)100000000;
                case 9:return (CONT)1000000000;
                default :return (CONT)-1;
            }
        }
        Bignum(){ bitlen=1; bit[0]=0; flag=false;}
        ~Bignum(){}
        Bignum(CONT x){
            if(x<0) flag=true,x=-x;
            else flag=false;
            bitlen=0;
            if(!x) bit[bitlen++]=0;
            while(x){
                bit[bitlen++]=x%WID;
                x/=WID;
            }
        }
        Bignum(char str[]){
            const int wid=(int)sizeof(CONT);
            int end;
            if(str[0]=='-'){ end=1; flag=true; }else { end=0; flag=false; }
            int i;
            CONT mid=0,p=0;
            for(i=0;str[i];i++);--i;
            for(bitlen=0;i>=end;i--){
                mid+=getpw(p)*(str[i]-'0'); p++;
                if(p>=wid){ bit[bitlen++]=mid; p=0; mid=0; }
            }
            if(mid)bit[bitlen++]=mid;
            for(i=bitlen-1;i>0&&!bit[i];i--); bitlen=i+1;
            if(flag&&bitlen==1&&bit[0]==0)flag=false;
        }
        void sprint(CONT x){
            if(x<0) flag=true,x=-x;
            else flag=false;
            bitlen=0;
            if(!x) bit[bitlen++]=0;
            while(x){
                bit[bitlen++]=x%WID;
                x/=WID;
            }
        }
        void sprint(char str[]){
            const int wid=(int)sizeof(CONT);
            int end;
            if(str[0]=='-'){ end=1; flag=true; }else { end=0; flag=false; }
            int i;
            CONT mid=0,p=0;
            for(i=0;str[i];i++);--i;
            for(bitlen=0;i>=end;i--){
                mid+=getpw(p)*(str[i]-'0'); p++;
                if(p>=wid){ bit[bitlen++]=mid; p=0; mid=0; }
            }
            if(mid)bit[bitlen++]=mid;
            for(i=bitlen-1;i>0&&!bit[i];i--); bitlen=i+1;
            if(flag&&bitlen==1&&bit[0]==0)flag=false;
        }
        bool scan(){
            char str[VV*((int)sizeof(CONT))+1];
            int ret=scanf("%s",str);
            sprint(str);
            return ret!=-1;
        }
        void print(){
            const int wid=(int)sizeof(CONT);
            if(flag)  putchar('-');
            if(wid==(int)sizeof(int)){
                printf("%d",bit[bitlen-1]);
                for(int i=bitlen-2;i>=0;i--) printf("%04d",bit[i]);
            }
            else{
                printf("%I64d",bit[bitlen-1]);
                for(int i=bitlen-2;i>=0;i--) printf("%08I64d",bit[i]);
            }
        }
        friend istream& operator>>(istream &in,Bignum &b){
            char str[VV*((int)sizeof(CONT))+1];
            in>>str;
            b.sprint(str);
            return in;
        }
        friend ostream& operator<<(ostream &out,Bignum b){
            out<<b.bit[b.bitlen-1];
            for(int i=b.bitlen-2;i>=0;i--){
                out.width((int)sizeof(CONT));
                out.fill('0');
                out<<b.bit[i];
            }
            return out;
        }
        void zero(){ for(int i=0;i<VV;i++)bit[i]=0; bitlen=1; bit[0]=0; flag=false; }
        bool ZERO(){ return (bitlen==1&&bit[0]==0); }
        bool odd(){ return bit[0]&1; }
        void negation(){
            flag=!flag;
            if(flag&&bitlen==1&&bit[0]==0)flag=false;
        }
        void abs(){ if(flag)flag=false; }
        void details(char *str = "num"){
            printf("[%s->bitlen = %d]\n[%s->flag = %d]\n",str,bitlen,str,flag);
        }
        friend bool operator==(Bignum &a,Bignum &b){
            if(a.flag!=b.flag||a.bitlen!=b.bitlen) return false;
            for(int i=a.bitlen-1;i>=0;i--) if(a.bit[i]!=b.bit[i]) return false;
            return true;
        }
        friend bool operator!=(Bignum &a,Bignum &b){ return !(a==b); }
        friend bool operator==(Bignum &a,CONT &b){ Bignum c(b); return a==c; }
        friend bool operator==(CONT &a,Bignum &b){ return b==a; }
        friend bool operator!=(Bignum &a,CONT &b){ Bignum c(b); return a!=c; }
        friend bool operator!=(CONT &a,Bignum &b){ return b!=a; }
        friend bool operator>(Bignum &a,Bignum &b){
            if(a.flag==b.flag){
                if(a.bitlen==b.bitlen){
                    if(a.flag){
                        for(int i=a.bitlen-1;i>=0;i--)
                            if(a.bit[i]!=b.bit[i]) return a.bit[i]<b.bit[i];
                    }
                    else{
                        for(int i=a.bitlen-1;i>=0;i--)
                            if(a.bit[i]!=b.bit[i]) return a.bit[i]>b.bit[i];
                    }
                    return false;
                }
                if(a.flag) return a.bitlen<b.bitlen;
                return a.bitlen>b.bitlen;
            }
            return b.flag;
        }
        friend bool operator>(Bignum &a,CONT &b){ Bignum c(b); return a>c; }
        friend bool operator>(CONT &a,Bignum &b){ Bignum c(a); return c>b; }
        friend bool operator<(Bignum &a,Bignum &b){ return b>a; }
        friend bool operator<(Bignum &a,CONT &b){ Bignum c(b); return a<c; }
        friend bool operator<(CONT &a,Bignum &b){ Bignum c(a); return c<b; }
        friend bool operator>=(Bignum &a,Bignum &b){ return (a>b||a==b); }
        friend bool operator>=(Bignum &a,CONT &b){ Bignum c(b); return a>=c; }
        friend bool operator>=(CONT &a,Bignum &b){ Bignum c(a); return c>=b; }
        friend bool operator<=(Bignum &a,Bignum &b){ return (a<b||a==b); }
        friend bool operator<=(Bignum &a,CONT &b){ Bignum c(b); return a<=c; }
        friend bool operator<=(CONT &a,Bignum &b){ Bignum c(a); return c<=b; }
        friend Bignum operator-(Bignum &a){
            Bignum c=a; c.flag=!c.flag;
            if(c.flag&&c.bitlen==1&&c.bit[0]==0)c.flag=false;
            return c;
        }
        friend Bignum operator+(Bignum a,Bignum b){
            Bignum ans((CONT)0);
            if(a.ZERO()) return b; if(b.ZERO()) return a;
            if(a.flag==b.flag){
                ans.flag=a.flag;
                int len=a.bitlen; if(b.bitlen>len) len=b.bitlen;
                ans.bitlen=len;
                int c=0;
                for(int i=0;i<len;i++){
                    if(i>=a.bitlen){
                        ans.bit[i]=b.bit[i]+c; c=ans.bit[i]/WID; if(ans.bit[i]>=WID) ans.bit[i]%=WID;
                        continue;
                    }
                    else if(i>=b.bitlen){
                        ans.bit[i]=a.bit[i]+c; c=ans.bit[i]/WID; if(ans.bit[i]>=WID) ans.bit[i]%=WID;
                        continue;
                    }
                    else {
                        ans.bit[i]=a.bit[i]+b.bit[i]+c; c=ans.bit[i]/WID; if(ans.bit[i]>=WID) ans.bit[i]%=WID;
                    }
                }
                if(c) ans.bit[len++]=c;
                ans.bitlen=len;
                return ans;
            }
            else{
                if(a.flag){
                    a.abs();
                    if(a>b) ans.flag=true;
                    else { ans=a; a=b; b=ans; ans.flag=false; }
                }
                else{
                    b.abs();
                    if(a>b) ans.flag=false;
                    else { ans=a; a=b; b=ans; ans.flag=true; }
                }
                int len=a.bitlen;
                for(int i=0;i<len;i++){
                    if(i>=b.bitlen){
                        ans.bit[i]=a.bit[i];
                        continue;
                    }
                    if(a.bit[i]<b.bit[i]){
                        a.bit[i]+=WID;
                        a.bit[i+1]-=1;
                    }
                    ans.bit[i]=a.bit[i]-b.bit[i];
                }
                for(len=len-1;len>0&&ans.bit[len]==0;len--);
                ans.bitlen=len+1;
                return ans;
            }
        }
        friend Bignum operator-(Bignum &a,Bignum b){
            b.negation();
            return a+b;
        }
        friend Bignum operator/(Bignum &a,CONT b){
            Bignum ans;
            if((a.flag&&b<0)||(!a.flag&&b>=0))ans.flag=false;
            else ans.flag=true;
            if(b<0)b=-b;
            CONT c=0;
            for(int i=a.bitlen-1;i>=0;i--){
                c=c*WID+a.bit[i];
                ans.bit[i]=c/b;
                if(c>=b)
                    c%=b;
            }
            int len;
            for(len=a.bitlen-1;len>0&&ans.bit[len]==0;len--);
            ans.bitlen=len+1;
            return ans;
        }
        friend Bignum operator*(Bignum &a,Bignum &b){
            Bignum ans;
            if(a.ZERO()||b.ZERO()) return ans;
            if(a.flag==b.flag) ans.flag=false;
            else ans.flag=true;
            ans.bitlen=a.bitlen+b.bitlen;
            for(int i=0;i<ans.bitlen;i++)ans.bit[i]=0;
            for(int i=0;i<a.bitlen;i++){
                for(int j=0;j<b.bitlen;j++){
                    int k=i+j;
                    ans.bit[k]+=a.bit[i]*b.bit[j];
                    ans.bit[k+1]+=ans.bit[k]/WID;
                    if(ans.bit[k]>=WID) ans.bit[k]%=WID;
                }
            }
            while(ans.bit[ans.bitlen-1]==0&&ans.bitlen>1) ans.bitlen--;
            return ans;
        }
        friend CONT operator%(Bignum &a,CONT b){
            int ret=1;
            if(a.flag) ret=-1;
            if(b<0) b=-b;
            CONT c=0;
            for(int i=a.bitlen-1;i>=0;i--){
                c=c*WID+a.bit[i];
                if(c>=b) c%=b;
            }
            return ret*c;
        }
        friend Bignum operator*(Bignum a,CONT b){
            if((a.flag&&b<0)||(!a.flag&&b>=0)) a.flag=false;
            else a.flag=true;
            if(b<0)b=-b;
            int c=0;
            int len=a.bitlen;
            for(int i=0;i<len;i++){
                a.bit[i]=a.bit[i]*b+c;
                c=a.bit[i]/WID;
                if(a.bit[i]>=WID) a.bit[i]%=WID;
            }
            while(c){
                a.bit[len++]=c%WID;
                c/=WID;
            }
            a.bitlen=len;
            return a;
        }
        friend Bignum operator*(CONT a,Bignum b){ return b*a; }
        friend Bignum operator+(Bignum a,CONT b){ Bignum ans(b); return a+ans; }
        friend Bignum operator+(CONT a,Bignum b){ return b+a; }
        friend Bignum operator^(Bignum a,CONT p){
            Bignum ret(1);
            for(;p;p>>=1){
                if(p&1)ret=ret*a;
                a=a*a;
            }
            return ret;
        }
};


这里大数是大整型,可以大数比较大小,输入输出流,大数乘法,大数加减法,大数的普通整型次幂,大数与普通整型取余与除法。

可以有负数。


HDU1002,HDU1042以及  http://192.168.100.16/diy/contest_show.php?cid=11954  这个DIY的1005能AC。


另外HDU1402大数乘法这个题目将VV设置到100010然后用G++也能过。只不过稍微慢了点,因为没有用FFT,FFT正在学习中,等学会了更新有FFT的版本。


1402:

int main()
{
    Bignum a,b,c;
    while(a.scan(),b.scan())
    {
        c=a*b;
        c.print();puts("");
    }
}

输入输出流:

int main()
{
    Bignum a,b,c;
    while(cin>>a>>b)
    {
        c=a*b;
        cout<<c<<endl;
    }
}
前者953MS,后者984MS。。。。。。运气不好就超时了。。。。


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值