- 2023tyoi0932 的博客
高精度模版
- 2024-4-2 13:09:26 @
注意:最高性能的高精度在最后面的版本里。
介绍也有。
这里简单的介绍一下用法。
small_int<10000> a;
这表示我们声明了一个可以存储 的一个数组。
所以我们的用法应该是:
small_int<size> a;
那么,这里可存数字的范围就是 的范围。
注意:只有可存数字范围相同的才可以互相进行运算,如果真的要,请先赋值再进行操作。
版本介绍
目前最高版本为: 版本或 版本
注意:我们常用的高精度版本为 1.2.01.04 版本,只有碰到了特殊高精度才需要考虑 1.3.01.04 版本
而且在不是高精度乘低精度这种需要优化的方面上的话,是不需要换版本的。
版本
特性:加法处理 ,减法处理 ,乘法处理 ,高精度除高精度处理 ,高精度除低精度处理 ,高精度乘低精度处理 ,高精 高精处理 ,拥有各种比较操作(除了不等于和非和与这种位运算),时间复杂度均为 ,且没有什么特别优化。
此版本介绍:
函数:可以求最大值、最小值的函数。
但不过你需要先定义一个 ,如:
我现在定义一个 ,访问方式即为 ,有两个参数,都为 类型。
注意:这个函数只是返回他的最大值,并不会把这两个数的最大值赋值为自己。
函数:和 一样,只不过使用来求最小值的。
函数:用来把 类型(或者 ,整数类型除了 、 都可以)给转化成 类型。
注意:这个函数也只是返回他转化后的样子,不会把这个数赋值给自己。访问方式如 函数。
函数:输入函数,没有参数。
函数:输出函数,里面有一个参数,参数类型为 ,如果没有,默认输出换行,否则在输出完这个数字后会输出该参数里面的东西。
函数:返回目前有几位的函数。( 会被当成是 位数)
函数:清空本 里面的数字,即相当于把它变成 。
注意:这个结构体里面的数字不会出现 ,就算是你的输入是 ,也不予理睬,只会是正 。
函数:有 参数类型,可以不需要输入,直接从字符串类型转换到 类型。
函数:我们定义了 和 直接的相乘,也定义了 和 直接的相乘。
注意事项 :如果你要把 类型和 类型直接相乘,请你先写 的类型变量,再写 类型的变量,这样可以防止一些奇怪的编译错误。
注意事项 :我们并没有定义 这些符号以及 这些位运算符号。
运算:取模,注意不能用负数取模。
我们定义了 和 直接的取模,也定义了 和 直接的取模。
注意: 不可以取模 类型。
等函数:比较运算符,也可以直接和 比较。
注意事项 :如果你要把 类型和 类型直接比较,请你先写 的类型变量,再写 类型的变量,这样可以防止一些奇怪的编译错误。
注意事项 :我们并没有定义 符号。
函数:交换函数。
假设我现在定义一个 的变量 和 ,现在我们想要交换 ,可以这样写:
或 。
但是请注意,假设我现在又有一个同样的类型 ,我们并不可以写 这一类的函数,这样会导致是 和 或 交换,反而不是 和 交换。
代码:
template<int const_size> class small_int{
public:
int a[const_size],fu;
small_int(){
to_empty();
fu=0;
}
int& operator [](const int x){
return a[x];
}
small_int pub_int(long long x){
small_int<const_size> c;
if(x<0) c.fu=1,x=-x;
int cnt=-1;
while(x>0){
c[++cnt]=x%10;
x/=10;
}
return c;
}
void out(const string s="\n"){
int i=const_size-1;
while(i>0 && a[i]==0) --i;
if(i==0 && a[i]==0){
cout<<0;
cout<<s;
return ;
}
if(fu) cout<<"-";
for(;i>=0;--i) cout<<a[i];
cout<<s;
return ;
}
int size(){
int n=const_size-1;
while(n>0 && a[n]==0) --n;
return n+1;
}
void to_empty(){
for(int i=0;i<const_size;++i) a[i]=0;
return ;
}
void in(){
string s;
cin>>s;
bool flag=0;
if(s[0]=='-') fu=1,s=s.substr(1,s.length()-1);
int len=s.length();
to_empty();
for(int i=0,j=len-1;i<len;++i,--j) a[i]=s[j]-'0',flag=(a[i]!='0' ? 1 : flag);
if(!flag) fu=0;
return ;
}
void duru(string s){
bool flag=0;
if(s[0]=='-') fu=1,s=s.substr(1,s.length()-1);
int len=s.length();
to_empty();
for(int i=0,j=len-1;i<len;++i,--j) a[i]=s[j]-'0',flag=(a[i]!='0' ? 1 : flag);
if(!flag) fu=0;
return ;
}
small_int operator + (small_int b){
small_int<const_size> c;
if(fu==1 && b.fu==1){
c.fu=1;
for(int i=0;i<const_size;++i){
c[i]+=a[i]+b[i];
if(c[i]>=10 && i+1<const_size) ++c[i+1],c[i]-=10;
}
}else if(fu==0 && b.fu==0){
for(int i=0;i<const_size;++i){
c[i]+=a[i]+b[i];
if(c[i]>=10 && i+1<const_size) ++c[i+1],c[i]-=10;
}
}else{
small_int<const_size> c,d;
for(int i=0;i<const_size;++i) d[i]=a[i];
c=(fu==1 && b.fu==0 ? b-d : d-b);
}
return c;
}
small_int operator + (long long B){
small_int<const_size> b;
if(B<0) b.fu=1,B=-B;
int cnt=-1;
while(B>0){
b[++cnt]=B%10;
B/=10;
}
small_int<const_size> c;
if(fu==1 && b.fu==1){
c.fu=1;
for(int i=0;i<const_size;++i){
c[i]+=a[i]+b[i];
if(c[i]>=10 && i+1<const_size) ++c[i+1],c[i]-=10;
}
}else if(fu==0 && b.fu==0){
for(int i=0;i<const_size;++i){
c[i]+=a[i]+b[i];
if(c[i]>=10 && i+1<const_size) ++c[i+1],c[i]-=10;
}
}else{
small_int<const_size> c,d;
for(int i=0;i<const_size;++i) d[i]=a[i];
c=(fu==1 && b.fu==0 ? b-d : d-b);
}
return c;
}
// 1234567
// -1208396
bool operator > (small_int b){
if(fu==0 && b.fu==1) return 1;
if(fu==1 && b.fu==0) return 0;
if(b.fu==0 && fu==0){
for(int i=const_size-1;i>=0;--i){
if(a[i]<b[i]) return 0;
if(a[i]>b[i]) return 1;
}
return 0;
}else{
for(int i=const_size-1;i>=0;--i){
if(a[i]<b[i]) return 1;
if(a[i]>b[i]) return 0;
}
return 0;
}
}
bool operator > (long long B){
small_int<const_size> b=pub_int(B);
if(fu==0 && b.fu==1) return 1;
if(fu==1 && b.fu==0) return 0;
if(b.fu==0 && fu==0){
for(int i=const_size-1;i>=0;--i){
if(a[i]<b[i]) return 0;
if(a[i]>b[i]) return 1;
}
return 0;
}else{
for(int i=const_size-1;i>=0;--i){
if(a[i]<b[i]) return 1;
if(a[i]>b[i]) return 0;
}
return 0;
}
}
bool operator >= (small_int b){
if(fu==0 && b.fu==1) return 1;
if(fu==1 && b.fu==0) return 0;
if(b.fu==0 && fu==0){
for(int i=const_size-1;i>=0;--i){
if(a[i]<b[i]) return 0;
if(a[i]>b[i]) return 1;
}
return 1;
}else{
for(int i=const_size-1;i>=0;--i){
if(a[i]<b[i]) return 1;
if(a[i]>b[i]) return 0;
}
return 1;
}
}
bool operator >= (long long B){
small_int<const_size> b=pub_int(B);
if(fu==0 && b.fu==1) return 1;
if(fu==1 && b.fu==0) return 0;
if(b.fu==0 && fu==0){
for(int i=const_size-1;i>=0;--i){
if(a[i]<b[i]) return 0;
if(a[i]>b[i]) return 1;
}
return 1;
}else{
for(int i=const_size-1;i>=0;--i){
if(a[i]<b[i]) return 1;
if(a[i]>b[i]) return 0;
}
return 1;
}
}
bool operator < (small_int b){
if(fu==0 && b.fu==1) return 1;
if(fu==1 && b.fu==0) return 0;
if(b.fu==0 && fu==0){
for(int i=const_size-1;i>=0;--i){
if(a[i]>b[i]) return 0;
if(a[i]<b[i]) return 1;
}
return 0;
}else{
for(int i=const_size-1;i>=0;--i){
if(a[i]>b[i]) return 1;
if(a[i]<b[i]) return 0;
}
return 0;
}
}
bool operator < (long long B){
small_int<const_size> b=pub_int(B);
if(fu==0 && b.fu==1) return 1;
if(fu==1 && b.fu==0) return 0;
if(b.fu==0 && fu==0){
for(int i=const_size-1;i>=0;--i){
if(a[i]>b[i]) return 0;
if(a[i]<b[i]) return 1;
}
return 0;
}else{
for(int i=const_size-1;i>=0;--i){
if(a[i]>b[i]) return 1;
if(a[i]<b[i]) return 0;
}
return 0;
}
}
bool operator <= (small_int b){
if(fu==0 && b.fu==1) return 1;
if(fu==1 && b.fu==0) return 0;
if(b.fu==0 && fu==0){
for(int i=const_size-1;i>=0;--i){
if(a[i]>b[i]) return 0;
if(a[i]<b[i]) return 1;
}
return 1;
}else{
for(int i=const_size-1;i>=0;--i){
if(a[i]>b[i]) return 1;
if(a[i]<b[i]) return 0;
}
return 1;
}
}
bool operator <= (long long B){
small_int<const_size> b=pub_int(B);
if(fu==0 && b.fu==1) return 1;
if(fu==1 && b.fu==0) return 0;
if(b.fu==0 && fu==0){
for(int i=const_size-1;i>=0;--i){
if(a[i]>b[i]) return 0;
if(a[i]<b[i]) return 1;
}
return 1;
}else{
for(int i=const_size-1;i>=0;--i){
if(a[i]>b[i]) return 1;
if(a[i]<b[i]) return 0;
}
return 1;
}
}
void swap(small_int &b){
small_int<const_size> c;
for(int i=0;i<const_size;++i) c[i]=b[i];
for(int i=0;i<const_size;++i) b[i]=a[i];
for(int i=0;i<const_size;++i) a[i]=c[i];
return ;
}
bool operator == (small_int b){
if(b.fu!=fu) return 0;
for(int i=const_size-1;i>=0;--i){
if(a[i]!=b[i]) return 0;
}
return 1;
}
bool operator == (long long B){
small_int<const_size> b=B;
if(b.fu!=fu) return 0;
for(int i=const_size-1;i>=0;--i){
if(a[i]!=b[i]) return 0;
}
return 1;
}
small_int operator - (long long B){
small_int<const_size> b;
if(B<0) b.fu=1,B=-B;
int cnt=-1;
while(B>0){
b[++cnt]=B%10;
B/=10;
}
small_int<const_size> c;
if(fu==0 && b.fu==0){
small_int<const_size> d;
for(int i=0;i<const_size;++i) d[i]=a[i];
if(b>d) d.swap(b),c.fu=1;
for(int i=0;i<const_size;++i){
c[i]+=d[i]-b[i];
if(c[i]<0){
if(i+1<const_size) c[i]+=10,--c[i+1];
}
}
}else if(fu==0 && b.fu==1){
small_int<const_size> d;
for(int i=0;i<const_size;++i) d[i]=a[i];
b.fu=0;
c=d+b;
}else if(fu==1 && b.fu==1){
small_int<const_size> d;
for(int i=0;i<const_size;++i) d[i]=a[i];
b.fu=0;
c=b-d;
}else if(fu==1 && b.fu==0){
small_int<const_size> d,e;
for(int i=0;i<const_size;++i) d[i]=a[i];
d.fu=1;
b.fu=1;
c=b+d;
}
return c;
}
small_int operator - (small_int b){
small_int<const_size> c;
if(fu==0 && b.fu==0){
small_int<const_size> d;
for(int i=0;i<const_size;++i) d[i]=a[i];
if(b>d) d.swap(b),c.fu=1;
for(int i=0;i<const_size;++i){
c[i]+=d[i]-b[i];
if(c[i]<0){
if(i+1<const_size) c[i]+=10,--c[i+1];
}
}
}else if(fu==0 && b.fu==1){
small_int<const_size> d;
for(int i=0;i<const_size;++i) d[i]=a[i];
b.fu=0;
c=d+b;
}else if(fu==1 && b.fu==1){
small_int<const_size> d;
for(int i=0;i<const_size;++i) d[i]=a[i];
b.fu=0;
c=b-d;
}else if(fu==1 && b.fu==0){
small_int<const_size> d,e;
for(int i=0;i<const_size;++i) d[i]=a[i];
d.fu=1;
b.fu=1;
c=b+d;
}
return c;
}
small_int operator * (small_int b){
small_int<const_size> c;
if(fu==1 && b.fu==1 || fu==0 && b.fu==0){
for(int i=0;i<const_size;++i){
if(a[i]==0) continue;
for(int j=0;j<const_size;++j){
if(i+j>=const_size) break;
c[i+j]+=a[i]*b[j];
if(c[i+j]>=10){
if(i+j+1<const_size) c[i+j+1]+=c[i+j]/10;
c[i+j]%=10;
}
}
}
}else{
c.fu=1;
for(int i=0;i<const_size;++i){
if(a[i]==0) continue;
for(int j=0;j<const_size;++j){
if(i+j>=const_size) break;
c[i+j]+=a[i]*b[j];
if(c[i+j]>=10){
if(i+j+1<const_size) c[i+j+1]+=c[i+j]/10;
c[i+j]%=10;
}
}
}
}
return c;
}
small_int operator * (long long B){
small_int<const_size> b;
if(B<0) b.fu=1,B=-B;
int cnt=-1;
while(B>0){
b[++cnt]=B%10;
B/=10;
}
small_int<const_size> c;
if(fu==1 && b.fu==1 || fu==0 && b.fu==0){
for(int i=0;i<const_size;++i){
if(a[i]==0) continue;
for(int j=0;j<const_size;++j){
if(i+j>=const_size) break;
c[i+j]+=a[i]*b[j];
if(c[i+j]>=10){
if(i+j+1<const_size) c[i+j+1]+=c[i+j]/10;
c[i+j]%=10;
}
}
}
}else{
c.fu=1;
for(int i=0;i<const_size;++i){
if(a[i]==0) continue;
for(int j=0;j<const_size;++j){
if(i+j>=const_size) break;
c[i+j]+=a[i]*b[j];
if(c[i+j]>=10){
if(i+j+1<const_size) c[i+j+1]+=c[i+j]/10;
c[i+j]%=10;
}
}
}
}
return c;
}
small_int operator / (long long b){
small_int<const_size> c,A;
for(int i=0;i<const_size;++i) A[i]=a[i];
if((int)fu+(b<0)==1) c.fu=1;
if(b<0) b=-b;
long long yu=0;
for(int i=const_size-1;i>=0;--i){
yu=yu*10+A[i];
c[i]=yu/b;
yu%=b;
}
return c;
}
long long operator % (long long b){
small_int<const_size> c,A;
for(int i=0;i<const_size;++i) A[i]=a[i];
if((int)fu+(b<0)==1) c.fu=1;
if(b<0) b=-b;
long long yu=0;
for(int i=const_size-1;i>=0;--i){
yu=yu*10+A[i];
c[i]=yu/b;
yu%=b;
}
return yu;
}
small_int operator / (small_int b){
small_int<const_size> yu;
small_int<const_size> c,A;
for(int i=0;i<const_size;++i) A[i]=a[i];
if((int)fu+(int)b.fu==1) c.fu=1;
b.fu=0;
for(int i=const_size-1;i>=0;--i){
yu=yu*10+A[i];
if(yu>=b){
long long l=1,r=9;
while(l<=r){
long long mid=(l+r)>>1;
if(yu>=b*mid) l=mid+1; // r=ans
else r=mid-1;
}
c[i]=r;
yu=yu-b*r;
}
}
return c;
}
small_int operator % (small_int b){
small_int<const_size> yu;
small_int<const_size> c,A;
for(int i=0;i<const_size;++i) A[i]=a[i];
if((int)fu+(int)b.fu==1) c.fu=1;
b.fu=0;
for(int i=const_size-1;i>=0;--i){
yu=yu*10+A[i];
if(yu>=b){
long long l=1,r=9;
while(l<=r){
long long mid=(l+r)>>1;
if(yu>=b*mid) l=mid+1; // r=ans
else r=mid-1;
}
c[i]=r;
yu=yu-b*r;
}
}
return yu;
}
void operator = (small_int o){
for(int i=0;i<const_size;++i) a[i]=o[i];
fu=o.fu;
return ;
}
void operator = (long long o){
small_int<const_size> b=pub_int(o);
for(int i=0;i<const_size;++i) a[i]=b[i];
fu=b.fu;
return ;
}
small_int pub_max(small_int a,small_int b){
if(a>b) return a;
return b;
}
small_int pub_min(small_int a,small_int b){
if(a<b) return a;
return b;
}
};
版本
改进:可以求一个数的 (长度),高精度乘低精度乘法优化到 ,于 年 月 日优化到 , 为低精度的那个数的长度;高精度除以高精度的除法优化到 ,高精 高精处理 ,时间复杂度降了好多,可以使用其操作一些复杂的高精度功能,比较的时间复杂度也因此而降低。
此版本介绍:
函数:可以求最大值、最小值的函数。
但不过你需要先定义一个 ,如:
我现在定义一个 ,访问方式即为 ,有两个参数,都为 类型。
注意:这个函数只是返回他的最大值,并不会把这两个数的最大值赋值为自己。
函数:和 一样,只不过使用来求最小值的。
函数:用来把 类型(或者 ,整数类型除了 、 都可以)给转化成 类型。
注意:这个函数也只是返回他转化后的样子,不会把这个数赋值给自己。访问方式如 函数。
函数:输入函数,没有参数。
函数:输出函数,里面有一个参数,参数类型为 ,如果没有,默认输出换行,否则在输出完这个数字后会输出该参数里面的东西。
函数:返回目前有几位的函数。( 会被当成是 位数)
与上个版本不同的是,这个函数可以 求出结果,但是上面的版本需要 才能求出来。
函数:清空本 里面的数字,即相当于把它变成 。
注意:这个结构体里面的数字不会出现 ,就算是你的输入是 ,也不予理睬,只会是正 。
函数:有 参数类型,可以不需要输入,直接从字符串类型转换到 类型。
函数:我们定义了 和 直接的相乘,也定义了 和 直接的相乘。
与上个版本不同的是: 和 直接运算的时候,除法从 优化成了 ,乘法的时间复杂度、加法的时间复杂度都有巨大的变化,模运算也如此。
注意事项 :如果你要把 类型和 类型直接相乘,请你先写 的类型变量,再写 类型的变量,这样可以防止一些奇怪的编译错误。
注意事项 :我们并没有定义 这些符号以及 这些位运算符号。
等函数:比较运算符,也可以直接和 比较。
注意事项 :如果你要把 类型和 类型直接比较,请你先写 的类型变量,再写 类型的变量,这样可以防止一些奇怪的编译错误。
注意事项 :我们并没有定义 符号。
运算:取模,注意不能用负数取模。
我们定义了 和 直接的取模,也定义了 和 直接的取模。
注意: 不可以取模 类型。
函数:交换函数。
假设我现在定义一个 的变量 和 ,现在我们想要交换 ,可以这样写:
或 。
但是请注意,假设我现在又有一个同样的类型 ,我们并不可以写 这一类的函数,这样会导致是 和 或 交换,反而不是 和 交换。
上一个版本的 :
假设你开了个长度为 的 ,但是里面的数只不过是 范围的,这个 会导致这个东西乘起来会耗费 的时间,并且导致时间超过了一秒。但是,这个版本已经修复了这个 ,并且时间复杂度更低了。
如果你试了,那你肯定知道:开了 确实会超时很严重。
但不过用上这个版本就不一样了。
输出部分的快慢已经通过调整。
之前的输出 :
假设我们定义一个变量 ,里面的数字是 ,但不过因为你申请了一个 的空间,所以他会每次从 的地方开始循环。
然后,每次应该要循环到 才停止,开始输出。
注意:他是倒序循环,每次 。
但是,假设你要输出 遍这个数,哪怕你开了 ,恐怕也要超时。
现在,不会有这个问题了,因为我们维护了 ,直接从 倒序输出即可。
这样就不会超时啦~
之前空间的 :
如果你在 函数外面申请了一片空间,长度为 ,他会立马爆掉。
为什么呢?
因为他用的是栈空间。
每一个变量都是用的占空间,这就导致了空间非常受限。
所以,我特地修复了这个 ,用 存了起来。
代码:
template<int const_size> class small_int{
public:
vector<long long> a;
int fu;
small_int(){
a.resize(const_size);
to_empty();
fu=0;
siz=1;
}
long long& operator [](const int x){
return a[x];
}
small_int pub_int(long long x){
small_int<const_size> c;
if(x<0) c.fu=1,x=-x;
int cnt=-1;
if(x==0){
c.siz=1;
return c;
}
while(x>0){
c[++cnt]=x%10;
x/=10;
}
c.siz=cnt+1;
return c;
}
void out(const string s="\n"){
if(siz==1 && a[0]==0) {cout<<0<<s;return ;}
if(fu) cout<<"-";
for(int i=siz-1;i>=0;--i) cout<<a[i];
cout<<s;
return ;
}
int size(){
return siz;
}
void to_empty(){
for(int i=0;i<const_size;++i) a[i]=0;
siz=0;
fu=0;
return ;
}
void in(){
string s;
cin>>s;
bool flag=0;
if(s[0]=='-') fu=1,s=s.substr(1,s.length()-1);
int len=s.length();
to_empty();
for(int i=0,j=len-1;i<len;++i,--j) a[i]=s[j]-'0',flag=(a[i]!='0' ? 1 : flag);
--len;
while(len>0 && a[len]==0) --len;
siz=len+1;
if(!flag) fu=0,siz=1;
return ;
}
void duru(string s){
bool flag=0;
if(s[0]=='-') fu=1,s=s.substr(1,s.length()-1);
int len=s.length();
to_empty();
for(int i=0,j=len-1;i<len;++i,--j) a[i]=s[j]-'0',flag=(a[i]!='0' ? 1 : flag);
--len;
while(len>0 && a[len]==0) --len;
siz=len;
if(!flag) fu=0,siz=1;
return ;
}
small_int operator + (small_int b){
small_int<const_size> c;
int up=min(max(siz,b.siz)+1,const_size);
if(fu==1 && b.fu==1){
c.fu=1;
for(int i=0;i<up;++i){
c[i]+=a[i]+b[i];
if(c[i]>=10 && i+1<const_size) ++c[i+1],c[i]-=10,c.siz=max(c.siz,i+2);
if(c[i]>0) c.siz=max(c.siz,i+1);
}
}else if(fu==0 && b.fu==0){
for(int i=0;i<up;++i){
c[i]+=a[i]+b[i];
if(c[i]>=10 && i+1<const_size) ++c[i+1],c[i]-=10,c.siz=max(c.siz,i+2);
if(c[i]>0) c.siz=max(c.siz,i+1);
}
}else{
small_int<const_size> c,d;
for(int i=0;i<const_size;++i) d[i]=a[i];
c=(fu==1 && b.fu==0 ? b-d : d-b);
}
return c;
}
small_int operator + (long long B){
small_int<const_size> b=pub_int(B);
small_int<const_size> c;
int up=min(max(b.siz,siz)+1,const_size);
if(fu==1 && b.fu==1){
c.fu=1;
for(int i=0;i<up;++i){
c[i]+=a[i]+b[i];
if(c[i]>=10 && i+1<const_size) ++c[i+1],c[i]-=10,c.siz=max(c.siz,i+2);
if(c[i]>0) c.siz=max(c.siz,i+1);
}
}else if(fu==0 && b.fu==0){
for(int i=0;i<up;++i){
c[i]+=a[i]+b[i];
if(c[i]>=10 && i+1<const_size) ++c[i+1],c[i]-=10,c.siz=max(c.siz,i+2);
if(c[i]>0) c.siz=max(c.siz,i+1);
}
}else{
small_int<const_size> d;
for(int i=0;i<const_size;++i) d[i]=a[i];
d.siz=siz;
c=(fu==1 && b.fu==0 ? b-d : d-b);
}
return c;
}
// 1234567
// -1208396
bool operator > (small_int b){
if(fu==0 && b.fu==1) return 1;
if(fu==1 && b.fu==0) return 0;
if(b.fu==0 && fu==0){
if(siz>b.siz) return 1;
else if(siz<b.siz) return 0;
for(int i=const_size-1;i>=0;--i){
if(a[i]<b[i]) return 0;
if(a[i]>b[i]) return 1;
}
return 0;
}else{
if(siz<b.siz) return 1;
else if(siz>b.siz) return 0;
for(int i=const_size-1;i>=0;--i){
if(a[i]<b[i]) return 1;
if(a[i]>b[i]) return 0;
}
return 0;
}
}
bool operator > (long long B){
small_int<const_size> b=pub_int(B);
if(fu==0 && b.fu==1) return 1;
if(fu==1 && b.fu==0) return 0;
if(b.fu==0 && fu==0){
if(siz>b.siz) return 1;
else if(siz<b.siz) return 0;
for(int i=const_size-1;i>=0;--i){
if(a[i]<b[i]) return 0;
if(a[i]>b[i]) return 1;
}
return 0;
}else{
if(siz<b.siz) return 1;
else if(siz>b.siz) return 0;
for(int i=const_size-1;i>=0;--i){
if(a[i]<b[i]) return 1;
if(a[i]>b[i]) return 0;
}
return 0;
}
}
bool operator >= (small_int b){
if(fu==0 && b.fu==1) return 1;
if(fu==1 && b.fu==0) return 0;
if(b.fu==0 && fu==0){
if(siz>b.siz) return 1;
else if(siz<b.siz) return 0;
for(int i=const_size-1;i>=0;--i){
if(a[i]<b[i]) return 0;
if(a[i]>b[i]) return 1;
}
return 1;
}else{
if(siz<b.siz) return 1;
else if(siz>b.siz) return 0;
for(int i=const_size-1;i>=0;--i){
if(a[i]<b[i]) return 1;
if(a[i]>b[i]) return 0;
}
return 1;
}
}
bool operator >= (long long B){
small_int<const_size> b=pub_int(B);
if(fu==0 && b.fu==1) return 1;
if(fu==1 && b.fu==0) return 0;
if(b.fu==0 && fu==0){
if(siz>b.siz) return 1;
else if(siz<b.siz) return 0;
for(int i=const_size-1;i>=0;--i){
if(a[i]<b[i]) return 0;
if(a[i]>b[i]) return 1;
}
return 1;
}else{
if(siz<b.siz) return 1;
else if(siz>b.siz) return 0;
for(int i=const_size-1;i>=0;--i){
if(a[i]<b[i]) return 1;
if(a[i]>b[i]) return 0;
}
return 1;
}
}
bool operator < (small_int b){
if(fu==0 && b.fu==1) return 1;
if(fu==1 && b.fu==0) return 0;
if(b.fu==0 && fu==0){
if(siz<b.siz) return 1;
else if(siz>b.siz) return 0;
for(int i=const_size-1;i>=0;--i){
if(a[i]>b[i]) return 0;
if(a[i]<b[i]) return 1;
}
return 0;
}else{
if(siz>b.siz) return 1;
else if(siz<b.siz) return 0;
for(int i=const_size-1;i>=0;--i){
if(a[i]>b[i]) return 1;
if(a[i]<b[i]) return 0;
}
return 0;
}
}
bool operator < (long long B){
small_int<const_size> b=pub_int(B);
if(fu==0 && b.fu==1) return 1;
if(fu==1 && b.fu==0) return 0;
if(b.fu==0 && fu==0){
if(siz<b.siz) return 1;
else if(siz>b.siz) return 0;
for(int i=const_size-1;i>=0;--i){
if(a[i]>b[i]) return 0;
if(a[i]<b[i]) return 1;
}
return 0;
}else{
if(siz>b.siz) return 1;
else if(siz<b.siz) return 0;
for(int i=const_size-1;i>=0;--i){
if(a[i]>b[i]) return 1;
if(a[i]<b[i]) return 0;
}
return 0;
}
}
bool operator <= (small_int b){
if(fu==0 && b.fu==1) return 1;
if(fu==1 && b.fu==0) return 0;
if(b.fu==0 && fu==0){
if(siz<b.siz) return 1;
else if(siz>b.siz) return 0;
for(int i=const_size-1;i>=0;--i){
if(a[i]>b[i]) return 0;
if(a[i]<b[i]) return 1;
}
return 1;
}else{
if(siz>b.siz) return 1;
else if(siz<b.siz) return 0;
for(int i=const_size-1;i>=0;--i){
if(a[i]>b[i]) return 1;
if(a[i]<b[i]) return 0;
}
return 1;
}
}
bool operator <= (long long B){
small_int<const_size> b=pub_int(B);
if(fu==0 && b.fu==1) return 1;
if(fu==1 && b.fu==0) return 0;
if(b.fu==0 && fu==0){
if(siz<b.siz) return 1;
else if(siz>b.siz) return 0;
for(int i=const_size-1;i>=0;--i){
if(a[i]>b[i]) return 0;
if(a[i]<b[i]) return 1;
}
return 1;
}else{
if(siz>b.siz) return 1;
else if(siz<b.siz) return 0;
for(int i=const_size-1;i>=0;--i){
if(a[i]>b[i]) return 1;
if(a[i]<b[i]) return 0;
}
return 1;
}
}
void swap(small_int &b){
small_int<const_size> c;
for(int i=0;i<const_size;++i) c[i]=b[i];
for(int i=0;i<const_size;++i) b[i]=a[i];
for(int i=0;i<const_size;++i) a[i]=c[i];
return ;
}
bool operator == (small_int b){
if(b.fu!=fu || siz!=b.siz) return 0;
for(int i=const_size-1;i>=0;--i){
if(a[i]!=b[i]) return 0;
}
return 1;
}
bool operator == (long long B){
small_int<const_size> b=B;
if(b.fu!=fu || siz!=b.siz) return 0;
for(int i=const_size-1;i>=0;--i){
if(a[i]!=b[i]) return 0;
}
return 1;
}
small_int operator - (long long B){
small_int<const_size> b=pub_int(B);
small_int<const_size> c;
if(fu==0 && b.fu==0){
small_int<const_size> d;
for(int i=0;i<const_size;++i) d[i]=a[i];
d.siz=siz;
if(b>d) d.swap(b),c.fu=1;
for(int i=0;i<const_size;++i){
c[i]+=d[i]-b[i];
if(c[i]<0){
if(i+1<const_size) c[i]+=10,--c[i+1];
}
}
int i=const_size-1;
while(i>0 && c[i]<=0) --i;
c.siz=i+1;
}else if(fu==0 && b.fu==1){
small_int<const_size> d;
for(int i=0;i<const_size;++i) d[i]=a[i];
d.siz=siz;
b.fu=0;
c=d+b;
}else if(fu==1 && b.fu==1){
small_int<const_size> d;
for(int i=0;i<const_size;++i) d[i]=a[i];
d.siz=siz;
b.fu=0;
c=b-d;
}else if(fu==1 && b.fu==0){
small_int<const_size> d,e;
for(int i=0;i<const_size;++i) d[i]=a[i];
d.siz=siz;
d.fu=1;
b.fu=1;
c=b+d;
}
return c;
}
small_int operator - (small_int b){
small_int<const_size> c;
if(fu==0 && b.fu==0){
small_int<const_size> d;
for(int i=0;i<const_size;++i) d[i]=a[i];
d.siz=siz;
if(b>d) d.swap(b),c.fu=1;
for(int i=0;i<const_size;++i){
c[i]+=d[i]-b[i];
if(c[i]<0){
if(i+1<const_size) c[i]+=10,--c[i+1];
}
}
int i=const_size-1;
while(i>0 && c[i]<=0) --i;
c.siz=i+1;
}else if(fu==0 && b.fu==1){
small_int<const_size> d;
for(int i=0;i<const_size;++i) d[i]=a[i];
d.siz=siz;
b.fu=0;
c=d+b;
}else if(fu==1 && b.fu==1){
small_int<const_size> d;
for(int i=0;i<const_size;++i) d[i]=a[i];
d.siz=siz;
b.fu=0;
c=b-d;
}else if(fu==1 && b.fu==0){
small_int<const_size> d,e;
for(int i=0;i<const_size;++i) d[i]=a[i];
d.siz=siz;
d.fu=1;
b.fu=1;
c=b+d;
}
return c;
}
small_int operator * (small_int b){
small_int<const_size> c;
if(fu==1 && b.fu==1 || fu==0 && b.fu==0){
int upi=min(siz+1,const_size),upj=min(b.siz+1,const_size);
for(int i=0;i<upi;++i){
if(a[i]==0) continue;
for(int j=0;j<upj;++j){
if(i+j>=const_size) break;
c[i+j]+=a[i]*b[j];
if(c[i+j]>0) c.siz=max(c.siz,i+j+1);
if(c[i+j]>=10){
if(i+j+1<const_size) c[i+j+1]+=c[i+j]/10,c.siz=max(c.siz,i+j+2);
c[i+j]%=10;
}
}
}
}else{
c.fu=1;
int upi=min(siz+1,const_size),upj=min(b.siz+1,const_size);
for(int i=0;i<upi;++i){
if(a[i]==0) continue;
for(int j=0;j<upj;++j){
if(i+j>=const_size) break;
c[i+j]+=a[i]*b[j];
if(c[i+j]>0) c.siz=max(c.siz,i+j+1);
if(c[i+j]>=10){
if(i+j+1<const_size) c[i+j+1]+=c[i+j]/10,c.siz=max(c.siz,i+j+2);
c[i+j]%=10;
}
}
}
}
return c;
}
small_int operator * (long long B){
small_int<const_size> c;
if(fu==1 && B<0 || fu==0 && B>=0){
int upi=min(siz+1,const_size);
for(int i=0;i<upi;++i) c[i]=a[i]*B;
for(int i=0;i<const_size;++i){
if(c[i]>0) c.siz=max(c.siz,i+1);
if(c[i]>=10){
if(i+1<const_size) c[i+1]+=c[i]/10,c.siz=max(c.siz,i+1);
c[i]%=10;
}
}
}else{
c.fu=1;
B=-B;
int upi=min(siz+1,const_size);
int nowmax=0;
for(int i=0;i<upi;++i){
c[i]=a[i]*B;
if(c[i]>0) nowmax=i;
}
for(int i=0;i<const_size;++i){
if(c[i]>0) c.siz=max(c.siz,i+1);
if(c[i]>=10){
if(i+1<const_size) c[i+1]+=c[i]/10,c.siz=max(c.siz,i+1);
c[i]%=10;
}
}
}
return c;
}
small_int operator / (long long b){
small_int<const_size> c,A;
for(int i=0;i<const_size;++i) A[i]=a[i];
A.siz=siz;
if((int)fu+(b<0)==1) c.fu=1;
if(b<0) b=-b;
long long yu=0;
for(int i=min(A.siz,const_size-1);i>=0;--i){
yu=yu*10+A[i];
c[i]=yu/b;
if(c[i]>0 && c.siz==1) c.siz=i+1;
yu%=b;
}
return c;
}
long long operator % (long long b){
small_int<const_size> A;
for(int i=0;i<const_size;++i) A[i]=a[i];
A.siz=siz;
if(b<0) b=-b;
long long yu=0;
for(int i=min(A.siz,const_size-1);i>=0;--i){
yu=yu*10+A[i];
yu%=b;
}
return yu;
}
small_int operator / (small_int b){
small_int<const_size> yu;
small_int<const_size> c,A;
for(int i=0;i<const_size;++i) A[i]=a[i];
A.siz=siz;
if((int)fu+(int)b.fu==1) c.fu=1;
b.fu=0;
for(int i=min(A.siz,const_size-1);i>=0;--i){
yu=yu*10+A[i];
if(yu>=b){
long long l=1,r=9;
while(l<=r){
long long mid=(l+r)>>1;
if(yu>=b*mid) l=mid+1; // r=ans
else r=mid-1;
}
c[i]=r;
yu=yu-b*r;
if(c[i]>0 && c.siz==1) c.siz=i+1;
}
}
return c;
}
small_int operator % (small_int b){
small_int<const_size> yu;
small_int<const_size> A;
for(int i=0;i<const_size;++i) A[i]=a[i];
A.siz=siz;
for(int i=min(A.siz,const_size-1);i>=0;--i){
yu=yu*10+A[i];
if(yu>=b){
long long l=1,r=9;
while(l<=r){
long long mid=(l+r)>>1;
if(yu>=b*mid) l=mid+1; // r=ans
else r=mid-1;
}
yu=yu-b*r;
}
}
return yu;
}
void operator = (small_int o){
for(int i=0;i<const_size;++i) a[i]=o[i];
fu=o.fu;
siz=o.siz;
return ;
}
void operator = (long long o){
small_int<const_size> b=pub_int(o);
for(int i=0;i<const_size;++i) a[i]=b[i];
fu=b.fu;
siz=b.siz;
return ;
}
small_int pub_max(small_int a,small_int b){
if(a>b) return a;
return b;
}
small_int pub_min(small_int a,small_int b){
if(a<b) return a;
return b;
}
private:
int siz;
};
版本
这个地方不在赘述,和 版本几乎没有任何差别。(除了高精度时间复杂度)
这也是非常常用的高精度模版。但是 为不常用模版。
只不过是高精度乘低精度的时间复杂度为 而已,并未多大影响。
代码:
template<int const_size> class small_int{
public:
int a[const_size];
int fu;
small_int(){
to_empty();
fu=0;
siz=1;
}
int& operator [](const int x){
return a[x];
}
small_int pub_int(long long x){
small_int<const_size> c;
if(x<0) c.fu=1,x=-x;
int cnt=-1;
if(x==0){
c.siz=1;
return c;
}
while(x>0){
c[++cnt]=x%10;
x/=10;
}
c.siz=cnt+1;
return c;
}
void out(const string s="\n"){
if(siz==1 && a[0]==0) {cout<<0<<s;return ;}
if(fu) cout<<"-";
for(int i=siz-1;i>=0;--i) cout<<a[i];
cout<<s;
return ;
}
int size(){
return siz;
}
void to_empty(){
for(int i=0;i<const_size;++i) a[i]=0;
siz=0;
fu=0;
return ;
}
void in(){
string s;
cin>>s;
bool flag=0;
if(s[0]=='-') fu=1,s=s.substr(1,s.length()-1);
int len=s.length();
to_empty();
for(int i=0,j=len-1;i<len;++i,--j) a[i]=s[j]-'0',flag=(a[i]!='0' ? 1 : flag);
--len;
while(len>0 && a[len]==0) --len;
siz=len+1;
if(!flag) fu=0,siz=1;
return ;
}
void duru(string s){
bool flag=0;
if(s[0]=='-') fu=1,s=s.substr(1,s.length()-1);
int len=s.length();
to_empty();
for(int i=0,j=len-1;i<len;++i,--j) a[i]=s[j]-'0',flag=(a[i]!='0' ? 1 : flag);
--len;
while(len>0 && a[len]==0) --len;
siz=len;
if(!flag) fu=0,siz=1;
return ;
}
small_int operator + (small_int b){
small_int<const_size> c;
int up=min(max(siz,b.siz)+1,const_size);
if(fu==1 && b.fu==1){
c.fu=1;
for(int i=0;i<up;++i){
c[i]+=a[i]+b[i];
if(c[i]>=10 && i+1<const_size) ++c[i+1],c[i]-=10,c.siz=max(c.siz,i+2);
if(c[i]>0) c.siz=max(c.siz,i+1);
}
}else if(fu==0 && b.fu==0){
for(int i=0;i<up;++i){
c[i]+=a[i]+b[i];
if(c[i]>=10 && i+1<const_size) ++c[i+1],c[i]-=10,c.siz=max(c.siz,i+2);
if(c[i]>0) c.siz=max(c.siz,i+1);
}
}else{
small_int<const_size> c,d;
for(int i=0;i<const_size;++i) d[i]=a[i];
c=(fu==1 && b.fu==0 ? b-d : d-b);
}
return c;
}
small_int operator + (long long B){
small_int<const_size> b=pub_int(B);
small_int<const_size> c;
int up=min(max(b.siz,siz)+1,const_size);
if(fu==1 && b.fu==1){
c.fu=1;
for(int i=0;i<up;++i){
c[i]+=a[i]+b[i];
if(c[i]>=10 && i+1<const_size) ++c[i+1],c[i]-=10,c.siz=max(c.siz,i+2);
if(c[i]>0) c.siz=max(c.siz,i+1);
}
}else if(fu==0 && b.fu==0){
for(int i=0;i<up;++i){
c[i]+=a[i]+b[i];
if(c[i]>=10 && i+1<const_size) ++c[i+1],c[i]-=10,c.siz=max(c.siz,i+2);
if(c[i]>0) c.siz=max(c.siz,i+1);
}
}else{
small_int<const_size> d;
for(int i=0;i<const_size;++i) d[i]=a[i];
d.siz=siz;
c=(fu==1 && b.fu==0 ? b-d : d-b);
}
return c;
}
// 1234567
// -1208396
bool operator > (small_int b){
if(fu==0 && b.fu==1) return 1;
if(fu==1 && b.fu==0) return 0;
if(b.fu==0 && fu==0){
if(siz>b.siz) return 1;
else if(siz<b.siz) return 0;
for(int i=const_size-1;i>=0;--i){
if(a[i]<b[i]) return 0;
if(a[i]>b[i]) return 1;
}
return 0;
}else{
if(siz<b.siz) return 1;
else if(siz>b.siz) return 0;
for(int i=const_size-1;i>=0;--i){
if(a[i]<b[i]) return 1;
if(a[i]>b[i]) return 0;
}
return 0;
}
}
bool operator > (long long B){
small_int<const_size> b=pub_int(B);
if(fu==0 && b.fu==1) return 1;
if(fu==1 && b.fu==0) return 0;
if(b.fu==0 && fu==0){
if(siz>b.siz) return 1;
else if(siz<b.siz) return 0;
for(int i=const_size-1;i>=0;--i){
if(a[i]<b[i]) return 0;
if(a[i]>b[i]) return 1;
}
return 0;
}else{
if(siz<b.siz) return 1;
else if(siz>b.siz) return 0;
for(int i=const_size-1;i>=0;--i){
if(a[i]<b[i]) return 1;
if(a[i]>b[i]) return 0;
}
return 0;
}
}
bool operator >= (small_int b){
if(fu==0 && b.fu==1) return 1;
if(fu==1 && b.fu==0) return 0;
if(b.fu==0 && fu==0){
if(siz>b.siz) return 1;
else if(siz<b.siz) return 0;
for(int i=const_size-1;i>=0;--i){
if(a[i]<b[i]) return 0;
if(a[i]>b[i]) return 1;
}
return 1;
}else{
if(siz<b.siz) return 1;
else if(siz>b.siz) return 0;
for(int i=const_size-1;i>=0;--i){
if(a[i]<b[i]) return 1;
if(a[i]>b[i]) return 0;
}
return 1;
}
}
bool operator >= (long long B){
small_int<const_size> b=pub_int(B);
if(fu==0 && b.fu==1) return 1;
if(fu==1 && b.fu==0) return 0;
if(b.fu==0 && fu==0){
if(siz>b.siz) return 1;
else if(siz<b.siz) return 0;
for(int i=const_size-1;i>=0;--i){
if(a[i]<b[i]) return 0;
if(a[i]>b[i]) return 1;
}
return 1;
}else{
if(siz<b.siz) return 1;
else if(siz>b.siz) return 0;
for(int i=const_size-1;i>=0;--i){
if(a[i]<b[i]) return 1;
if(a[i]>b[i]) return 0;
}
return 1;
}
}
bool operator < (small_int b){
if(fu==0 && b.fu==1) return 1;
if(fu==1 && b.fu==0) return 0;
if(b.fu==0 && fu==0){
if(siz<b.siz) return 1;
else if(siz>b.siz) return 0;
for(int i=const_size-1;i>=0;--i){
if(a[i]>b[i]) return 0;
if(a[i]<b[i]) return 1;
}
return 0;
}else{
if(siz>b.siz) return 1;
else if(siz<b.siz) return 0;
for(int i=const_size-1;i>=0;--i){
if(a[i]>b[i]) return 1;
if(a[i]<b[i]) return 0;
}
return 0;
}
}
bool operator < (long long B){
small_int<const_size> b=pub_int(B);
if(fu==0 && b.fu==1) return 1;
if(fu==1 && b.fu==0) return 0;
if(b.fu==0 && fu==0){
if(siz<b.siz) return 1;
else if(siz>b.siz) return 0;
for(int i=const_size-1;i>=0;--i){
if(a[i]>b[i]) return 0;
if(a[i]<b[i]) return 1;
}
return 0;
}else{
if(siz>b.siz) return 1;
else if(siz<b.siz) return 0;
for(int i=const_size-1;i>=0;--i){
if(a[i]>b[i]) return 1;
if(a[i]<b[i]) return 0;
}
return 0;
}
}
bool operator <= (small_int b){
if(fu==0 && b.fu==1) return 1;
if(fu==1 && b.fu==0) return 0;
if(b.fu==0 && fu==0){
if(siz<b.siz) return 1;
else if(siz>b.siz) return 0;
for(int i=const_size-1;i>=0;--i){
if(a[i]>b[i]) return 0;
if(a[i]<b[i]) return 1;
}
return 1;
}else{
if(siz>b.siz) return 1;
else if(siz<b.siz) return 0;
for(int i=const_size-1;i>=0;--i){
if(a[i]>b[i]) return 1;
if(a[i]<b[i]) return 0;
}
return 1;
}
}
bool operator <= (long long B){
small_int<const_size> b=pub_int(B);
if(fu==0 && b.fu==1) return 1;
if(fu==1 && b.fu==0) return 0;
if(b.fu==0 && fu==0){
if(siz<b.siz) return 1;
else if(siz>b.siz) return 0;
for(int i=const_size-1;i>=0;--i){
if(a[i]>b[i]) return 0;
if(a[i]<b[i]) return 1;
}
return 1;
}else{
if(siz>b.siz) return 1;
else if(siz<b.siz) return 0;
for(int i=const_size-1;i>=0;--i){
if(a[i]>b[i]) return 1;
if(a[i]<b[i]) return 0;
}
return 1;
}
}
void swap(small_int &b){
small_int<const_size> c;
for(int i=0;i<const_size;++i) c[i]=b[i];
for(int i=0;i<const_size;++i) b[i]=a[i];
for(int i=0;i<const_size;++i) a[i]=c[i];
return ;
}
bool operator == (small_int b){
if(b.fu!=fu || siz!=b.siz) return 0;
for(int i=const_size-1;i>=0;--i){
if(a[i]!=b[i]) return 0;
}
return 1;
}
bool operator == (long long B){
small_int<const_size> b=B;
if(b.fu!=fu || siz!=b.siz) return 0;
for(int i=const_size-1;i>=0;--i){
if(a[i]!=b[i]) return 0;
}
return 1;
}
small_int operator - (long long B){
small_int<const_size> b=pub_int(B);
small_int<const_size> c;
if(fu==0 && b.fu==0){
small_int<const_size> d;
for(int i=0;i<const_size;++i) d[i]=a[i];
d.siz=siz;
if(b>d) d.swap(b),c.fu=1;
for(int i=0;i<const_size;++i){
c[i]+=d[i]-b[i];
if(c[i]<0){
if(i+1<const_size) c[i]+=10,--c[i+1];
}
}
int i=const_size-1;
while(i>0 && c[i]<=0) --i;
c.siz=i+1;
}else if(fu==0 && b.fu==1){
small_int<const_size> d;
for(int i=0;i<const_size;++i) d[i]=a[i];
d.siz=siz;
b.fu=0;
c=d+b;
}else if(fu==1 && b.fu==1){
small_int<const_size> d;
for(int i=0;i<const_size;++i) d[i]=a[i];
d.siz=siz;
b.fu=0;
c=b-d;
}else if(fu==1 && b.fu==0){
small_int<const_size> d,e;
for(int i=0;i<const_size;++i) d[i]=a[i];
d.siz=siz;
d.fu=1;
b.fu=1;
c=b+d;
}
return c;
}
small_int operator - (small_int b){
small_int<const_size> c;
if(fu==0 && b.fu==0){
small_int<const_size> d;
for(int i=0;i<const_size;++i) d[i]=a[i];
d.siz=siz;
if(b>d) d.swap(b),c.fu=1;
for(int i=0;i<const_size;++i){
c[i]+=d[i]-b[i];
if(c[i]<0){
if(i+1<const_size) c[i]+=10,--c[i+1];
}
}
int i=const_size-1;
while(i>0 && c[i]<=0) --i;
c.siz=i+1;
}else if(fu==0 && b.fu==1){
small_int<const_size> d;
for(int i=0;i<const_size;++i) d[i]=a[i];
d.siz=siz;
b.fu=0;
c=d+b;
}else if(fu==1 && b.fu==1){
small_int<const_size> d;
for(int i=0;i<const_size;++i) d[i]=a[i];
d.siz=siz;
b.fu=0;
c=b-d;
}else if(fu==1 && b.fu==0){
small_int<const_size> d,e;
for(int i=0;i<const_size;++i) d[i]=a[i];
d.siz=siz;
d.fu=1;
b.fu=1;
c=b+d;
}
return c;
}
small_int operator * (small_int b){
small_int<const_size> c;
if(fu==1 && b.fu==1 || fu==0 && b.fu==0){
int upi=min(siz+1,const_size),upj=min(b.siz+1,const_size);
for(int i=0;i<upi;++i){
if(a[i]==0) continue;
for(int j=0;j<upj;++j){
if(i+j>=const_size) break;
c[i+j]+=a[i]*b[j];
if(c[i+j]>0) c.siz=max(c.siz,i+j+1);
if(c[i+j]>=10){
if(i+j+1<const_size) c[i+j+1]+=c[i+j]/10,c.siz=max(c.siz,i+j+2);
c[i+j]%=10;
}
}
}
}else{
c.fu=1;
int upi=min(siz+1,const_size),upj=min(b.siz+1,const_size);
for(int i=0;i<upi;++i){
if(a[i]==0) continue;
for(int j=0;j<upj;++j){
if(i+j>=const_size) break;
c[i+j]+=a[i]*b[j];
if(c[i+j]>0) c.siz=max(c.siz,i+j+1);
if(c[i+j]>=10){
if(i+j+1<const_size) c[i+j+1]+=c[i+j]/10,c.siz=max(c.siz,i+j+2);
c[i+j]%=10;
}
}
}
}
return c;
}
small_int operator * (long long B){
small_int<const_size> b=pub_int(B);
small_int<const_size> c;
if(fu==1 && b.fu==1 || fu==0 && b.fu==0){
int upi=min(siz+1,const_size),upj=min(b.siz+1,const_size);
for(int i=0;i<upi;++i){
if(a[i]==0) continue;
for(int j=0;j<upj;++j){
if(i+j>=const_size) break;
c[i+j]+=a[i]*b[j];
if(c[i+j]>0) c.siz=max(c.siz,i+j+1);
if(c[i+j]>=10){
if(i+j+1<const_size) c[i+j+1]+=c[i+j]/10,c.siz=max(c.siz,i+j+2);
c[i+j]%=10;
}
}
}
}else{
c.fu=1;
int upi=min(siz+1,const_size),upj=min(b.siz+1,const_size);
for(int i=0;i<upi;++i){
if(a[i]==0) continue;
for(int j=0;j<upj;++j){
if(i+j>=const_size) break;
c[i+j]+=a[i]*b[j];
if(c[i+j]>0) c.siz=max(c.siz,i+j+1);
if(c[i+j]>=10){
if(i+j+1<const_size) c[i+j+1]+=c[i+j]/10,c.siz=max(c.siz,i+j+2);
c[i+j]%=10;
}
}
}
}
return c;
}
small_int operator / (long long b){
small_int<const_size> c,A;
for(int i=0;i<const_size;++i) A[i]=a[i];
A.siz=siz;
if((int)fu+(b<0)==1) c.fu=1;
if(b<0) b=-b;
long long yu=0;
for(int i=min(A.siz,const_size-1);i>=0;--i){
yu=yu*10+A[i];
c[i]=yu/b;
if(c[i]>0 && c.siz==1) c.siz=i+1;
yu%=b;
}
return c;
}
long long operator % (long long b){
small_int<const_size> A;
for(int i=0;i<const_size;++i) A[i]=a[i];
A.siz=siz;
if(b<0) b=-b;
long long yu=0;
for(int i=min(A.siz,const_size-1);i>=0;--i){
yu=yu*10+A[i];
yu%=b;
}
return yu;
}
small_int operator / (small_int b){
small_int<const_size> yu;
small_int<const_size> c,A;
for(int i=0;i<const_size;++i) A[i]=a[i];
A.siz=siz;
if((int)fu+(int)b.fu==1) c.fu=1;
b.fu=0;
for(int i=min(A.siz,const_size-1);i>=0;--i){
yu.fast_multiply(1);
yu=yu+A[i];
if(yu>=b){
long long l=1,r=9;
while(l<=r){
long long mid=(l+r)>>1;
if(yu>=b*mid) l=mid+1; // r=ans
else r=mid-1;
}
c[i]=r;
yu=yu-b*r;
if(c[i]>0 && c.siz==1) c.siz=i+1;
}
}
return c;
}
small_int operator % (small_int b){
small_int<const_size> yu;
small_int<const_size> A;
for(int i=0;i<const_size;++i) A[i]=a[i];
A.siz=siz;
for(int i=min(A.siz,const_size-1);i>=0;--i){
yu.fast_multiply(1);
yu=yu+A[i];
if(yu>=b){
long long l=1,r=9;
while(l<=r){
long long mid=(l+r)>>1;
if(yu>=b*mid) l=mid+1; // r=ans
else r=mid-1;
}
yu=yu-b*r;
}
}
return yu;
}
void operator = (small_int o){
for(int i=0;i<const_size;++i) a[i]=o[i];
fu=o.fu;
siz=o.siz;
return ;
}
void operator = (long long o){
small_int<const_size> b=pub_int(o);
for(int i=0;i<const_size;++i) a[i]=b[i];
fu=b.fu;
siz=b.siz;
return ;
}
small_int pub_max(small_int a,small_int b){
if(a>b) return a;
return b;
}
small_int pub_min(small_int a,small_int b){
if(a<b) return a;
return b;
}
private:
int siz;
void fast_multiply(int x){
for(int i=min(const_size-1,siz+x-1);i>=x;--i) a[i]=a[i-x];
for(int i=x-1;i>=0;--i) a[i]=0;
return ;
}
};
年 月 日:经过检查,每个版本均可正常运行,可以投入到正常的使用中了,于今日彻底完成这两个版本,更新了每一个版本的高精度功能介绍。
我们还更新了输出、空间方面的 。
年 月 日 点 分:因为我在拿这个高精度做某道题(自行查看)的时候,成功超时,最后只能调整高精度乘低精度的策略,将时间复杂度从 优化到了 。特殊版本 也从此诞生。
在这里插播一个小事情:
假设你用 版本去做洛谷 ,那么你会得到这个时间复杂度:
但不过你用特殊版本 版本去做的话,结果是:
所以,只有在特殊情况下,再动用特殊版本。不然你可能会死的很惨
注:把 版本中的 vector<long long>
改成 vector<int>
即可 ,但不过还是有点慢。
年 月 日:
在这里插播一件小事情。
就是,有一些特殊的题目必须手写高精度,不可以套用模版。
如:这道题,你套用模版会取得:
但不过,你手写会:
虽然套模板可能确实很快乐,因为不用打高精度了,但不过贪心总有下场的。
所以,可以套模板,但是注意适度哦~