高精度模板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]=‘\0‘;
		for3(i, len-1, 1) printf(od, (int)a[i]);
	}
};

  

时间: 2024-08-02 11:03:34

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

【原创】高精度(压位储存)模板

无聊写了个高精度模板玩玩...... 1 /* 2 高精度(压位储存) 3 */ 4 #include <cstdlib> 5 #include <iostream> 6 #include <cstdio> 7 #include <cstring> 8 #include <cmath> 9 const int MAX=10005;//最长长度 10 using namespace std; 11 //高精度结构体,先声明后实现 12 struct

高精度压位

压位的原因 正常的高精度计算中,每一位只存了一位数字,可是当面对比较大的计算的时候呢,如果说每一位都只存一位数字,那么计算的时间就会比较地长.这个时候可以通过每一位高精度中存储多位数字的方法来降低运算的时间 例题引入 简单的来说就是 一个高精度的开根号,只要求开到整数向下取整就可以了.数据范围是10^1000; 首先就是开高精度根号的方法,很容易想到的方法就是二分或者是手动开根号.我这里使用的是二分的方法. 这一道题最开始我是直接高精度来的,然后TLE了,接着我压了四位,还是TLE了,然后直接1

codevs 3119 高精度练习之大整数开根 (各种高精+压位)

/* codevs 3119 高精度练习之大整数开根 (各种高精+压位) 二分答案 然后高精判重 打了一个多小时..... 最后还超时了...压位就好了 测试点#1.in 结果:AC 内存使用量: 256kB 时间使用量: 0ms 测试点#2.in 结果:AC 内存使用量: 256kB 时间使用量: 1ms 测试点#3.in 结果:AC 内存使用量: 256kB 时间使用量: 0ms 测试点#4.in 结果:AC 内存使用量: 256kB 时间使用量: 10ms 测试点#5.in 结果:AC 内

高精度——压位的思想及应用

本文作者frankchenfu,blogs网址http://www.cnblogs.com/frankchenfu/,转载请保留此文字. 这里我们简单介绍一下高精度的计算. 我们都知道在Cpp/C/Pas等语言中,整数最大能储存\(2^{64} -1\),超过这个范围就表示不了了(不包括个别支持int128的编译器).这个时候,我们如果希望把这些整数存储下来,就需要用到高精度的算法和思想.高精度就是像小学学过的竖式运算一样的(除法除外).然后就直接模拟即可.除法一位一位地试商即可. 接下来我们发

[SDOI2009]SuperGCD 【压位高精度+辗转相减】

题目链接: https://www.luogu.org/problemnew/show/P2152 题目概述:  计算两个大整数(A,B)的最大公因数 数据范围 0 < A , B ≤ 10 ^ 其一在于辗转相减法--辗转相除法的优化(针对大数,避免了大数的模运算带来的多方面的复杂度) 思想就是 以数次 A-B  代替 A%B (这二者是等价的) 辗转相减法: 1 /* 2 Write(X) 输出X 3 Down(X) X除以2 4 Up(X) X乘以2 5 */ 6 void Solve(){

用到了卡特兰数的性质,还有高精度压位,筛法找素数

一列火车n节车厢,依次编号为1,2,3,-,n. 每节车厢有两种运动方式,进栈与出栈,问n节车厢出栈的可能排列方式有多少种. 输入格式 输入一个整数n,代表火车的车厢数. 输出格式 输出一个整数s表示n节车厢出栈的可能排列方式数量. 数据范围 1≤n≤60000 输入样例: 3 输出样例: 5 这道题的本质是卡特兰数 卡特兰数介绍(引用math73) 筛法求素数 最重要的是如何求解组合数,压位思想,还有组合数C(2n)(n)这个式子展开以后,用上下同时除以连续的质数的方法,将答案一点一点凑出来,

[Template]高精度模板

重新写一下高精度模板(不要问我为什么) 自认为代码风格比较漂亮(雾 如果有更好的写法欢迎赐教 封装结构体big B是压位用的进制,W是每位长度 size表示长度,d[]就是保存的数字,倒着保存,从1开始 #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; const i

高精度模板(不定时更新)

以前写高精度基本都是抄别人的--这次要改变一下了-- 现在的高精度模板还是很简陋的,只支持高精加,减,乘,高精除低精,高精模低精,高精快速幂,高精比较大小,没了. 或许以后会不定期更新一下--毕竟这个还是比较ca的. 直接一股脑全贴上来吧--注意所有的元素都是倒叙存储的,想要改成压位的很简单,只要改一下模数,改一下输入输出即可. 也可以支持不同进制的运算,都是很好改的. struct big { int f[M],len; big() { memset(f,0,sizeof(f)),len =

真&#183;纯手撸高精度模板

耗时(50分钟)不压位 内容只有高精度+-*,因为其他我不会写QAQ~ 均ACluogu,codevs #include<bits/stdc++.h> using namespace std; const int N =(int)1e5+10; struct bignum { int m[N],len; char str[N]; int ok; bignum() {ok=1;len=1,memset(m,0, sizeof(m));} void in() {scanf("%s&quo