二分压位高精度除法求调
  • 板块学术版
  • 楼主Crab_Tang
  • 当前回复21
  • 已保存回复21
  • 发布时间2024/4/15 09:29
  • 上次更新2024/4/16 18:34:50
查看原帖
二分压位高精度除法求调
1021365
Crab_Tang楼主2024/4/15 09:29
#include<bits/stdc++.h>
using namespace std;
struct bigint{
    int WIDTH=8;
    int BASE=1e8;
    static const int NUMSIZE=2000;
    int sign;//sign为-1是负数,1是正数
    int len;
    int num[NUMSIZE];
    bigint(){
        len=1,sign=1;
        memset(num,0,sizeof num);
    }
    bigint(string s){
        sign=1,len=ceil(((int)s.length())*1.0/WIDTH);
        bool ____k=(((int)s.length())%WIDTH);
        if(s[0]=='-')
            sign=-1,len=ceil((((int)s.length())-1)*1.0/WIDTH),____k=((((int)s.length())-1)%WIDTH);
        if(____k)
            num[len]=stoi(s.substr(((sign==1)?0:1),((((int)s.length())-(sign==1?0:1))%WIDTH)));
        for(int i=(____k?len-1:len);i>=1;--i)
            num[i]=stoi(s.substr(((int)s.length())-WIDTH*i,WIDTH));
        clear();
    }
    bigint(int x){
        if(x<0)
            sign=-1,x=-x;
        else
            sign=1;
        memset(num,0,sizeof num);
        len=0;
        do{
            ++len;
            num[len]=x%BASE;
            x/=BASE;
        }
        while(x);
        clear();
    }
    bigint(long long x){
        if(x<0)
            sign=-1,x=-x;
        else
            sign=1;
        memset(num,0,sizeof num);
        len=0;
        do{
            ++len;
            num[len]=x%BASE;
            x/=BASE;
        }
        while(x);
        clear();
    }
    int stoi(string s){
        int x=0;
        for(int i=0;i<((int)s.length());++i)
            x=x*10+s[i]-'0';
        return x;//return std::stoi(s);
    }
    void clear(){
        while(len>1&&num[len]==0)
            num[len--]=0;
        if(len==1&&num[len]==0&&sign==-1)
            sign=1;
        return;
    }
    void print(char c=' ',bool mode=0){
        if(!mode){
            if(sign==-1)
                putchar('-');
            printf("%d",num[len]);
            string s="%";
            s+="0";
            s+=(WIDTH+'0');
            s+="d";
            for(int i=len-1;i>=1;--i)
                printf(s.c_str(),num[i]);
            putchar(c);
            return;
        }
        for(int i=1;i<=len;++i)
            cout<<"num,"<<i<<":"<<num[i]<<'\n';
        cout<<"len:"<<len<<" sign:"<<sign;
        puts("");
        return;
    }
    bigint operator-(){
        bigint ans=(*this);
        if(!(ans.len==1&&ans.sign==1&&ans.num[len]==0))
            ans.sign*=-1;
        return ans;
    }
    bigint operator+(bigint x){
        if(x.sign==-1&&sign==1)
            return (*this)-(-x);
        if(sign==-1&&x.sign==1)
            return x-(-(*this));
        bigint ans;
        if(sign==-1&&x.sign==-1)
            ans.sign=-1;
        ans.len=max(len,x.len)+1;
        for(int i=1;i<=ans.len;++i){
            ans.num[i]+=num[i]+x.num[i];
            ans.num[i+1]=ans.num[i]/BASE;
            ans.num[i]=ans.num[i]%BASE;
        }
        ans.clear();
        return ans;
    }
    int cmp_bigint(bigint x,bigint y){//1代表等于,2代表小于,3代表大于
        if(x.sign<y.sign)//x负y正
            return 2;
        if(x.sign>y.sign)//x正y负
            return 3;
        if(x.sign==-1){//都是负
            if(x.len>y.len)//x长y短
                return 2;
            if(x.len<y.len)//y长x短
                return 3;
            for(int i=x.len;i>=1;--i){
                if(x.num[i]>y.num[i])
                    return 2;
                if(x.num[i]<y.num[i])
                    return 3;
            }
            return 1;
        }
        if(x.sign==1){//都是正
            if(x.len>y.len)//x长y短
                return 3;
            if(x.len<y.len)//y长x短
                return 2;
            for(int i=x.len;i>=1;--i){
                if(x.num[i]>y.num[i])
                    return 3;
                if(x.num[i]<y.num[i])
                    return 2;
            }
            return 1;
        }
        throw invalid_argument("cmp_bigint wrong");
    }
    bool operator<(bigint x){
        return cmp_bigint((*this),x)==2;
    }
    bool operator>(bigint x){
        return cmp_bigint((*this),x)==3;
    }
    bool operator==(bigint x){
        return cmp_bigint((*this),x)==1;
    }
    bool operator>=(bigint x){
        return (cmp_bigint((*this),x)==1)||(cmp_bigint((*this),x)==3);
    }
    bool operator<=(bigint x){
        return (cmp_bigint((*this),x)==1)||(cmp_bigint((*this),x)==2);
    }
    bigint operator+=(bigint x){
        return (*this)=(*this)+x;
    }
    bigint operator-=(bigint x){
        return (*this)=(*this)-x;
    }
    bigint operator*=(bigint x){
        return (*this)=(*this)*x;
    }
    bigint operator-(bigint x){
        if(x.sign==-1)
            return (*this)+(-x);
        if(sign==-1)
            return (*this)+(-x);
        if((*this)<x)
            return -(x-(*this));
        bigint ans;
        ans.len=len;
        for(int i=1;i<=ans.len;++i){
            ans.num[i]+=num[i]-x.num[i]+BASE;
            ans.num[i+1]=ans.num[i]/BASE-1;
            ans.num[i]%=BASE;
        }
        ans.clear();
        return ans;
    }
    bigint operator*(bigint x){
        if(x==1)
            return (*this);
        if((*this)==1)
            return x;
        if(x==0||(*this)==0)
            return 0;
        bigint ans;
        ans.len=len+x.len;
        if((x.sign==-1&&sign==1)||(sign==-1&&x.sign==1))
            ans.sign=-1;
        long long tmp_ans[NUMSIZE];
        for(int i=1;i<=len;++i)
            for(int j=1;j<=x.len;++j){
                tmp_ans[i+j-1]+=1ll*num[i]*x.num[j];
                tmp_ans[i+j]+=tmp_ans[i+j-1]/BASE;
                tmp_ans[i+j-1]%=BASE;
            }
        for(int i=1;i<=ans.len;++i)
            ans.num[i]=tmp_ans[i];
        ans.clear();
        return ans;
    }
    void push_bigint(int x){
        for(int i=len;i>=1;--i)
            num[i+1]=num[i];
        ++len;
        num[1]=x;
        clear();
    }
    pair<bigint,bigint>div_bigint(bigint x,bigint y){//pair<商,余数>
        if(y==0)
            throw invalid_argument("Denominator cannot be zero");
        if(x==0)
            return make_pair(0,0);
        if(y==1)
            return make_pair(x,0);
        if(x.sign==-1&&y.sign==-1){
            pair<bigint,bigint>tmp_bigint_pair=div_bigint(-x,-y);
            return make_pair(tmp_bigint_pair.first,-tmp_bigint_pair.second);
        }
        if(x.sign==-1){
            pair<bigint,bigint>tmp_bigint_pair=div_bigint(-x,y);
            return make_pair(-tmp_bigint_pair.first,-tmp_bigint_pair.second);
        }
        if(y.sign==-1){
            pair<bigint,bigint>tmp_bigint_pair=div_bigint(x,-y);
            return make_pair(-tmp_bigint_pair.first,tmp_bigint_pair.second);
        }
        if(x<y)
            return make_pair(0,x);
        bigint ans,___t;
        ans.len=x.len;
        for(int i=ans.len;i>=1;--i){
            ___t.push_bigint(x.num[i]);
            while(___t>=y){
                ++ans.num[i];
                ___t-=y;
            }
        }
        ans.clear();
        return make_pair(ans,___t);
    }
    pair<bigint,bigint>div_int(bigint x,int y){//pair<商,余数>
        if(y==0)
            throw invalid_argument("Denominator cannot be zero");
        if(x==0)
            return make_pair(0,0);
        if(y==1)
            return make_pair(x,0);
        if(x.sign==-1&&y<0){
            pair<bigint,bigint>tmp_bigint_pair=div_int(-x,-y);
            return make_pair(tmp_bigint_pair.first,-tmp_bigint_pair.second);
        }
        if(x.sign==-1){
            pair<bigint,bigint>tmp_bigint_pair=div_int(-x,y);
            return make_pair(-tmp_bigint_pair.first,-tmp_bigint_pair.second);
        }
        if(y<0){
            pair<bigint,bigint>tmp_bigint_pair=div_int(x,-y);
            return make_pair(-tmp_bigint_pair.first,tmp_bigint_pair.second);
        }
        if(x<y)
            return make_pair(0,x);
        bigint ans;
        long long ___t=0;
        ans.len=x.len;
        for(int i=ans.len;i>=1;--i){
            ___t=___t*BASE+x.num[i];
            ans.num[i]=___t/y;
            ___t=___t%y;
        }
        ans.clear();
        return make_pair(ans,___t);
    }
    bigint operator/(int x){
        return div_int((*this),x).first;
    }
    bigint operator%(int x){
        return div_int((*this),x).second;
    }
    pair<bigint,bigint>erfen_bigint(bigint x,bigint y){
        if(y==0)
            throw invalid_argument("Denominator cannot be zero");
        if(x==0)
            return make_pair(0,0);
        if(y==1)
            return make_pair(x,0);
        
        if(x.sign==-1&&y.sign==-1){
            pair<bigint,bigint>tmp_bigint_pair=div_bigint(-x,-y);
            return make_pair(tmp_bigint_pair.first,-tmp_bigint_pair.second);
        }
        if(x.sign==-1){
            pair<bigint,bigint>tmp_bigint_pair=div_bigint(-x,y);
            return make_pair(-tmp_bigint_pair.first,-tmp_bigint_pair.second);
        }
        if(y.sign==-1){
            pair<bigint,bigint>tmp_bigint_pair=div_bigint(x,-y);
            return make_pair(-tmp_bigint_pair.first,tmp_bigint_pair.second);
        }
        /*
         ans=l=1,r=a;
         while(r>=l)
         {
         m=(l+r)/2;
         if(m*b>a)
         r=m-1;
         else
         ans=m,l=m+1;
         }
         */
        if(x<y)
            return make_pair(0,x);
        bigint l,r=x,mid,cj,ans;
        while(r>=l){
            mid=(r+l);
            mid=mid/2;
            cj=mid*y;
            if(cj>x){
                r=mid-1;
            }
            else
                l=mid+1,ans=mid;
        }
        ans.clear();
        return make_pair(ans,(x-(y*ans)));
    }
};
int main(){
    system("color A");
    string sa,sb;
    cin>>sa>>sb;
    bigint a=sa,b=sb;
    a=a.erfen_bigint(a,b).first;
    a.print();
    /*
    string sa,sb;
    cin>>sa>>sb;
    bigint a=sa,b=sb;
    a*=b;
    a.print();
    */
    /*
    string sa;
    int b;
    cin>>sa>>b;
    bigint a=sa;
    a=a/b;
    a.print();
    */
    return 0;
}

玄关

二分高精度在erfen_bigint里边

2024/4/15 09:29
加载中...