码迷,mamicode.com
首页 > 其他好文 > 详细

高精度模板2(带符号压位加减乘除开方封包)

时间:2014-11-23 00:29:59      阅读:221      评论:0      收藏:0      [点我收藏+]

标签:blog   http   io   ar   os   sp   for   on   div   

原来的那个模板:http://www.cnblogs.com/iwtwiioi/p/3991331.html 估计已经不用了。

现在我重新封包好了一个,一定很好用QAQ

加减乘除带开方带压位带重载运算符

注意一下符号即可,一定写的时候要手推四种情况!!

然后在重载<的时候,一定要注意同时判断!!!!要不然又错。。

struct big {
	typedef ll INT;
	static const INT S=100000000;
	static const int S_n=9;
	static const int SIZE=305;
	INT a[SIZE]; int len, tag;
	big() { len=1; CC(a, 0); }
	big(char *s) { len=1; CC(a, 0); *this=s; }
	big(INT x) { len=1; CC(a, 0); *this=x; }
	void cln() { memset(a, 0, sizeof(INT)*(len+1)); len=1; tag=0; }
	void fix() { while(len>1 && !a[len]) --len; }
	void M(big &a, big &b, big &c) {
		if(b.tag) { b.tag=0; P(a, b, c); b.tag=1; return; }
		if(a.tag) { a.tag=0; P(a, b, c); a.tag=1; c.tag=1; return; }
		c.cln();
		int flag=0, i=1;
		big *x=&a, *y=&b;
		if(a<b) flag=1, swap(x, y);
		for(; i<=x->len; ++i) {
			c.a[i]+=x->a[i]-y->a[i];
			if(c.a[i]<0) c.a[i]+=S, --c.a[i+1];
		}
		c.len=i;
		c.fix();
		c.tag=flag;
	}
	void P(big &a, big &b, big &c) {
		if(b.tag) { b.tag=0; M(a, b, c); b.tag=1; return; }
		if(a.tag) { a.tag=0; M(b, a, c); a.tag=1; return; }
		c.cln();
		int i=1, l=max(a.len, b.len); INT k=0;
		for(; i<=l || k; ++i) {
			c.a[i]=a.a[i]+b.a[i]+k;
			k=c.a[i]/S;
			if(c.a[i]>=S) c.a[i]%=S;
		}
		c.len=i;
		c.fix();
	}
	void T(big &a, big &b, big &c) {
		c.cln();
		for1(i, 1, a.len) for1(j, 1, b.len) {
			int pos=i+j-1;
			c.a[pos]+=a.a[i]*b.a[j];
			c.a[pos+1]+=c.a[pos]/S;
			c.a[pos]%=S;
		}
		c.len=a.len+b.len;
		c.fix();
		c.tag=a.tag^b.tag;
		if(c.a[1]==0 && c.len==1) c.tag=0;
	}
	void D(big &a, INT b, big &c) {
		c.cln(); INT t=0;
		for(int i=len; i; --i) {
			c.a[i]=(a.a[i]+t)/b;
			t=((a.a[i]+t)%b)*S;
		}
		c.len=len;
		c.fix();
	}
	void D(big &a, big &b, big &c) {
		c.cln();
		big l, r=a, mid, TP, ONE=(INT)1;
		while(l<=r) {
			P(l, r, TP); D(TP, 2, mid);
			T(mid, b, TP);
			if(TP<=a) P(mid, ONE, l);
			else M(mid, ONE, r);
		}
		M(l, ONE, c);
		c.tag=a.tag^b.tag;
		if(c.a[1]==0 && c.len==1) c.tag=0;
	}
	big sqrt() {
		big l, r=*this, mid, TP, ONE=(INT)1;
		while(l<=r) {
			P(l, r, TP); D(TP, 2, mid);
			T(mid, mid, TP);
			if(TP<=*this) P(mid, ONE, l);
			else M(mid, ONE, r);
		}
		M(l, ONE, TP);
		return TP;
	}
	bool operator<(big &b) {
		if(b.tag && !tag) return 0;
		if(!b.tag && tag) return 1;
		if(b.tag && tag) { tag=b.tag=0; bool ret=b<*this; tag=b.tag=1; return ret; }
		if(len!=b.len) return len<b.len;
		for3(i, len, 1) if(a[i]<b.a[i]) return true; else if(a[i]>b.a[i]) return false; //这里一定要注意
		return false;
	}
	big& operator= (INT b) {
		cln();
		len=0;
		if(b==0) { len=1; return *this; }
		if(b<0) tag=1, b=-b;
		while(b) { a[++len]=b%S; b/=S; }
		return *this;
	}
	big& operator= (char *s) {
		cln();
		if(s[0]==‘-‘) tag=1, ++s;
		len=0; int l=strlen(s), t=0, k=1;
		for3(i, l-1, 0) {
			t=t+(s[i]-‘0‘)*k;
			k*=10;
			if(k>=S) a[++len]=t%S, t=0, k=1;
		}
		if(k!=1) a[++len]=t%S;
		return *this;
	}
	big& operator= (const big &x) {
		cln();
		memcpy(a, x.a, sizeof(INT)*(x.len+1));
		len=x.len, tag=x.tag;
		return *this;
	}
	big operator+ (big x) { big c; P(*this, x, c); return c; }
	big operator- (big x) { big c; M(*this, x, c); return c; }
	big operator* (big x) { big c; T(*this, x, c); return c; }
	big operator/ (big x) { big c; D(*this, x, c); return c; }
	big operator/ (INT x) { big c; D(*this, x, c); return c; }
	big& operator+= (big x) { big c; P(*this, x, c); return *this=c; }
	big& operator-= (big x) { big c; M(*this, x, c); return *this=c; }
	big& operator*= (big x) { big c; T(*this, x, c); return *this=c; }
	big& operator/= (big x) { big c; D(*this, x, c); return *this=c; }
	big& operator/= (INT x) { big c; D(*this, x, c); return *this=c; }
	big& operator++ () { return *this+=1; }
	big operator++ (int) { big ret=*this; ++*this; return ret; }
	big& operator-- () { return *this-=1; }
	big operator-- (int) { big ret=*this; --*this; return ret; }
	bool operator> (big &x) { return x<*this; }
	bool operator== (big &x) { return x<=*this&&x>=*this; }
	bool operator<= (big &x) { return !(x<*this); }
	bool operator>= (big &x) { return !(x>*this); }
	void P() {
		if(tag) putchar(‘-‘);
		printf("%d", (int)a[len]);
		char od[8]; od[0]=‘%‘; od[1]=‘0‘;
		sprintf(od+2, "%d", S_n-1);
		int l=strlen(od); od[l]=‘d‘; od[l+1]=‘\0‘;
		for3(i, len-1, 1) printf(od, (int)a[i]);
	}
};

  

高精度模板2(带符号压位加减乘除开方封包)

标签:blog   http   io   ar   os   sp   for   on   div   

原文地址:http://www.cnblogs.com/iwtwiioi/p/4115896.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!