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


    原来的那个模板: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]='';
    		for3(i, len-1, 1) printf(od, (int)a[i]);
    	}
    };
    

      

  • 相关阅读:
    子网掩码
    一个正则表达式:该正则表达式标示了后面有数字,但又不能是某特定数字的情况
    C++:STL标准入门汇总
    SOAP
    uva10236The Fibonacci Primes
    uvalive3209City Game
    uvalive3695Distant Galaxy
    uva11549Calculator Conundrum
    uva11078Open Credit System
    uvalive3295Counting Triangles
  • 原文地址:https://www.cnblogs.com/iwtwiioi/p/4115896.html
Copyright © 2020-2023  润新知