[模板]高精度

copy from DQS…..


题目:
codevs1331
codevs3115~3118

Tips:
1、为防爆栈加取地址符;
2、len的及时更新

求模数的话,在/最后返回a就可以了
但直接返回会re,不知道为什么

#include
#include
#include
#include
typedef long long LL;
using namespace std;
const int MAXN = 10000 + 50;
const int size = 100010;
const int base = (int)1e9;
struct bigint{
    LL len,num[MAXN];
    bigint(){memset(num,0,sizeof(num));len = 1;}
    bigint(LL x){
        /**/memset(num,0,sizeof(num));len = 0;
        while(x){
            num[++len] = x%base;
            x /= base;
        }
    }
};

void scanf(bigint &ans){
    string s;
    cin >> s;
    int l = s.length();
    ans.len = (l - 1)/size + 1;
    for(int i = 0;i < ans.len;i ++){
        int sy = l - i*size;
        int k = max(0,sy - size);
        LL x = 0;
        for(int j = k;j < k + sy - k;j ++){
            x = (x << 3) + (x << 1) + s[j] - '0';
        }
        ans.num[i + 1] = x;
    }
}

void printf(const bigint &ans){
    if(ans.num[ans.len + 1])printf("-");
    printf("%d",ans.num[ans.len]);//避免前导零 
    for(int i = ans.len - 1;i >= 1;i --){
        printf("%09d",ans.num[i]);
    }
}

bool operator < (bigint &a,bigint &b){
    if(a.len != b.len)return a.len < b.len;
    for(int i = 1;i <= a.len;i ++){
        if(a.num[i] != b.num[i])return a.num[i] < b.num[i];
    }
    return false;
}

bigint operator + (bigint &a,bigint &b){
    bigint ans;
    LL i = 1,x = 0;
    while(i <= a.len || i <= b.len){
        x += a.num[i] + b.num[i];
        ans.num[i ++] = x % base;
        x /= base;
    }
    ans.num[i] = x;
    ans.len = i;
    /**/while(ans.len > 1 && ans.num[ans.len] == 0)ans.len --;
    return ans;
}

bigint operator - (bigint &a,bigint &b){
    bool flag = false;
    if(a < b){
        flag = true;
        swap(a,b);
    }
    LL i = 1;
    while(i <= b.len){
        if(a.num[i] < b.num[i]){
            a.num[i + 1] --;
            a.num[i] += base;
        }
        a.num[i] -= b.num[i];
        i ++;
    }
    while(a.len > 1 && a.num[a.len] == 0)a.len --;
    if(flag)a.num[a.len + 1] = -1;
    return a;
}

bigint operator * (bigint &a,bigint &b){
    bigint ans;
    ans.len = a.len + b.len;
    for(int i = 1;i <= a.len;i ++){
        LL x = 0;
        for(int j = 1;j <= b.len;j ++){
            x += a.num[i]*b.num[j] + ans.num[i + j - 1];//!!
            ans.num[i + j - 1] = x%base;
            x /= base;
        }
        ans.num[i + b.len] = x;
    }
    /**/while(ans.len > 1 && ans.num[ans.len] == 0)ans.len --;
    return ans;
}
bool smaller(bigint &a,bigint &b,int d){
    if(a.len + d != b.len)return a.len + d < b.len;
    for(int i = a.len;i >= 1;i --){
        if(a.num[i] != b.num[i + d])
            return a.num[i] < b.num[i + d];
    }
    return true;
}
void jian(bigint &a,bigint &b,int d){
    for(int i = 1;i <= b.len;i ++){
        if(a.num[i + d] < b.num[i]){
            a.num[i + d + 1] --;
            a.num[i + d] += base;
        }
        a.num[i + d] -= b.num[i];
    }
    while(a.len > 1 && a.num[a.len] == 0)a.len --;
}
bigint tmp[32];
bigint operator /(bigint &a,bigint &b){//不加&,爆栈 
    bigint ans;
    ans.len = max(1LL,a.len - b.len + 1);
    tmp[0] = b;
    bigint two = 2LL;
    for(int i = 1;i <= 30;i ++)tmp[i] = tmp[i - 1]*two;
    for(int d = a.len - b.len;d >= 0;d --){
        LL now = 1 << 30;
        for(int i = 30;i >= 0;i --){
            if(smaller(tmp[i],a,d)){
                jian(a,tmp[i],d);
                ans.num[d + 1] += now;
            }
            now >>= 1;
        }
    }
    while(ans.len > 1 && ans.num[ans.len] == 0)ans.len --;
    return ans;
}
int main(){
    bigint a,b;
    scanf(a);
    scanf(b);
    printf(a/b);
    return 0;
}

你可能感兴趣的:(模版/模型,高精度)