[模板]高精度

copy from DQS.....


题目:
codevs1331
codevs3115~3118

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

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

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
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;
}
posted @ 2017-11-07 20:01  _平行  阅读(127)  评论(0编辑  收藏  举报