注意:最高性能的高精度在最后面的版本里。

介绍也有。

这里简单的介绍一下用法。

small_int<10000> a;

这表示我们声明了一个可以存储 1010000110^{10000}-1 的一个数组。

所以我们的用法应该是:

small_int<size> a;

那么,这里可存数字的范围就是 10size+110size1-10^{size}+1 \to 10^{size}-1 的范围。

注意:只有可存数字范围相同的才可以互相进行运算,如果真的要,请先赋值再进行操作。

版本介绍

目前最高版本为:1.3.01.041.3.01.04 版本或 1.2.01.041.2.01.04 版本

注意:我们常用的高精度版本为 1.2.01.04 版本,只有碰到了特殊高精度才需要考虑 1.3.01.04 版本

而且在不是高精度乘低精度这种需要优化的方面上的话,是不需要换版本的。

1.1.00.021.1.00.02 版本

特性:加法处理 O(n)\mathcal O(n),减法处理 O(n)\mathcal O(n),乘法处理 O(n2)\mathcal O(n^2),高精度除高精度处理 O(n3)\mathcal O(n^3),高精度除低精度处理 O(n)\mathcal O(n),高精度乘低精度处理 O(n2)\mathcal O(n^2),高精 modmod 高精处理 O(n3)\mathcal O(n^3),拥有各种比较操作(除了不等于和非和与这种位运算),时间复杂度均为 O(n)\mathcal O(n),且没有什么特别优化。

此版本介绍:

pub_maxpub\_max 函数:可以求最大值、最小值的函数。

但不过你需要先定义一个 small_intsmall\_int,如:

我现在定义一个 aa,访问方式即为 a.pub_max()a.pub\_max(),有两个参数,都为 small_intsmall\_int 类型。

注意:这个函数只是返回他的最大值,并不会把这两个数的最大值赋值为自己。

pub_minpub\_min 函数:和 maxmax 一样,只不过使用来求最小值的。

pub_intpub\_int 函数:用来把 long longlong~long 类型(或者 intint,整数类型除了 unsigned long longunsigned~long~long__int128\_\_int128 都可以)给转化成 small_intsmall\_int 类型。

注意:这个函数也只是返回他转化后的样子,不会把这个数赋值给自己。访问方式如 pub_maxpub\_max 函数。

inin 函数:输入函数,没有参数。

outout 函数:输出函数,里面有一个参数,参数类型为 stringstring,如果没有,默认输出换行,否则在输出完这个数字后会输出该参数里面的东西。

sizesize 函数:返回目前有几位的函数。( 00 会被当成是 11 位数)

to_emptyto\_empty 函数:清空本 small_intsmall\_int 里面的数字,即相当于把它变成 00

注意:这个结构体里面的数字不会出现 0-0,就算是你的输入是 0-0,也不予理睬,只会是正 00

duruduru 函数:有 stringstring 参数类型,可以不需要输入,直接从字符串类型转换到 small_intsmall\_int 类型。

+,,×,÷+,-,\times,\div 函数:我们定义了 small_intsmall\_intsmall_intsmall\_int 直接的相乘,也定义了 small_intsmall\_intlong longlong~long 直接的相乘。

注意事项 11:如果你要把 small_intsmall\_int 类型和 long longlong~long 类型直接相乘,请你先写 small_intsmall\_int 的类型变量,再写 long longlong~long 类型的变量,这样可以防止一些奇怪的编译错误。

注意事项 22:我们并没有定义 +=,=,×=,÷=+=,-=,\times=,\div= 这些符号以及 <<,>><<,>> 这些位运算符号。

%\% 运算:取模,注意不能用负数取模。

我们定义了 small_intsmall\_intsmall_intsmall\_int 直接的取模,也定义了 small_intsmall\_intlong longlong~long 直接的取模。

注意:long longlong~long 不可以取模 small_intsmall\_int 类型。

==,>,<,<=,>===,>,<,<=,>= 等函数:比较运算符,也可以直接和 long longlong~long 比较。

注意事项 11:如果你要把 small_intsmall\_int 类型和 long longlong~long 类型直接比较,请你先写 small_intsmall\_int 的类型变量,再写 long longlong~long 类型的变量,这样可以防止一些奇怪的编译错误。

注意事项 22:我们并没有定义 !=!= 符号。

swapswap 函数:交换函数。

假设我现在定义一个 small_intsmall\_int 的变量 aabb,现在我们想要交换 a,ba,b,可以这样写:

a.swap(b)a.swap(b)b.swap(a)b.swap(a)

但是请注意,假设我现在又有一个同样的类型 cc,我们并不可以写 c.swap(a),c.swap(b)c.swap(a),c.swap(b) 这一类的函数,这样会导致是 ccaabb 交换,反而不是 aabb 交换。

代码。

1.3.01.041.3.01.04 版本

改进:可以求一个数的 sizesize(长度),高精度乘低精度乘法优化到 O(n×len)\mathcal O(n \times len),于 202420244422 日优化到 O(n)\mathcal O(n)lenlen 为低精度的那个数的长度;高精度除以高精度的除法优化到 O(n2×log10)\mathcal O(n^2 \times \log10),高精 modmod 高精处理 O(n2×log10)\mathcal O(n^2 \times \log 10),时间复杂度降了好多,可以使用其操作一些复杂的高精度功能,比较的时间复杂度也因此而降低。

此版本介绍:

pub_maxpub\_max 函数:可以求最大值、最小值的函数。

但不过你需要先定义一个 small_intsmall\_int,如:

我现在定义一个 aa,访问方式即为 a.pub_max()a.pub\_max(),有两个参数,都为 small_intsmall\_int 类型。

注意:这个函数只是返回他的最大值,并不会把这两个数的最大值赋值为自己。

pub_minpub\_min 函数:和 maxmax 一样,只不过使用来求最小值的。

pub_intpub\_int 函数:用来把 long longlong~long 类型(或者 intint,整数类型除了 unsigned long longunsigned~long~long__int128\_\_int128 都可以)给转化成 small_intsmall\_int 类型。

注意:这个函数也只是返回他转化后的样子,不会把这个数赋值给自己。访问方式如 pub_maxpub\_max 函数。

inin 函数:输入函数,没有参数。

outout 函数:输出函数,里面有一个参数,参数类型为 stringstring,如果没有,默认输出换行,否则在输出完这个数字后会输出该参数里面的东西。

sizesize 函数:返回目前有几位的函数。( 00 会被当成是 11 位数)

与上个版本不同的是,这个函数可以 O(1)\mathcal O(1) 求出结果,但是上面的版本需要 O(n)\mathcal O(n) 才能求出来。

to_emptyto\_empty 函数:清空本 small_intsmall\_int 里面的数字,即相当于把它变成 00

注意:这个结构体里面的数字不会出现 0-0,就算是你的输入是 0-0,也不予理睬,只会是正 00

duruduru 函数:有 stringstring 参数类型,可以不需要输入,直接从字符串类型转换到 small_intsmall\_int 类型。

+,,×,÷+,-,\times,\div 函数:我们定义了 small_intsmall\_intsmall_intsmall\_int 直接的相乘,也定义了 small_intsmall\_intlong longlong~long 直接的相乘。

与上个版本不同的是:small_intsmall\_intsmall_intsmall\_int 直接运算的时候,除法从 O(n3)\mathcal O(n^3) 优化成了 O(log10×n2)\mathcal O(\log 10 \times n^2),乘法的时间复杂度、加法的时间复杂度都有巨大的变化,模运算也如此。

注意事项 11:如果你要把 small_intsmall\_int 类型和 long longlong~long 类型直接相乘,请你先写 small_intsmall\_int 的类型变量,再写 long longlong~long 类型的变量,这样可以防止一些奇怪的编译错误。

注意事项 22:我们并没有定义 +=,=,×=,÷=+=,-=,\times=,\div= 这些符号以及 <<,>><<,>> 这些位运算符号。

==,>,<,<=,>===,>,<,<=,>= 等函数:比较运算符,也可以直接和 long longlong~long 比较。

注意事项 11:如果你要把 small_intsmall\_int 类型和 long longlong~long 类型直接比较,请你先写 small_intsmall\_int 的类型变量,再写 long longlong~long 类型的变量,这样可以防止一些奇怪的编译错误。

注意事项 22:我们并没有定义 !=!= 符号。

%\% 运算:取模,注意不能用负数取模。

我们定义了 small_intsmall\_intsmall_intsmall\_int 直接的取模,也定义了 small_intsmall\_intlong longlong~long 直接的取模。

注意:long longlong~long 不可以取模 small_intsmall\_int 类型。

swapswap 函数:交换函数。

假设我现在定义一个 small_intsmall\_int 的变量 aabb,现在我们想要交换 a,ba,b,可以这样写:

a.swap(b)a.swap(b)b.swap(a)b.swap(a)

但是请注意,假设我现在又有一个同样的类型 cc,我们并不可以写 c.swap(a),c.swap(b)c.swap(a),c.swap(b) 这一类的函数,这样会导致是 ccaabb 交换,反而不是 aabb 交换。

上一个版本的 bugbug

假设你开了个长度为 2000020000small_intsmall\_int,但是里面的数只不过是 long longlong~long 范围的,这个 bugbug 会导致这个东西乘起来会耗费 O(n2)O(n^2) 的时间,并且导致时间超过了一秒。但是,这个版本已经修复了这个 bugbug,并且时间复杂度更低了。

如果你试了,那你肯定知道:开了 2000020000 确实会超时很严重。

但不过用上这个版本就不一样了。

输出部分的快慢已经通过调整。

之前的输出 bugbug

假设我们定义一个变量 aa,里面的数字是 114514114514,但不过因为你申请了一个 2×1062 \times 10^6 的空间,所以他会每次从 2×10612 \times 10^6-1 的地方开始循环。

然后,每次应该要循环到 55 才停止,开始输出。

注意:他是倒序循环,每次 i--i

但是,假设你要输出 10001000 遍这个数,哪怕你开了 O2O2,恐怕也要超时。

现在,不会有这个问题了,因为我们维护了 sizesize,直接从 size1size-1 倒序输出即可。

这样就不会超时啦~

之前空间的 bugbug

如果你在 mainmain 函数外面申请了一片空间,长度为 3×1053 \times 10^5,他会立马爆掉。

为什么呢?

因为他用的是栈空间。

每一个变量都是用的占空间,这就导致了空间非常受限。

所以,我特地修复了这个 bugbug,用 vectorvector 存了起来。

代码。

1.2.01.041.2.01.04 版本

这个地方不在赘述,和 1.3.01.041.3.01.04 版本几乎没有任何差别。(除了高精度时间复杂度)

这也是非常常用的高精度模版。但是 1.3.01.041.3.01.04 为不常用模版。

只不过是高精度乘低精度的时间复杂度为 O(n×len)\mathcal O(n \times len) 而已,并未多大影响。

代码。

UpdateUpdate:

202420244422 日:经过检查,每个版本均可正常运行,可以投入到正常的使用中了,于今日彻底完成这两个版本,更新了每一个版本的高精度功能介绍。

我们还更新了输出、空间方面的 bugbug

20242024442218181313 分:因为我在拿这个高精度做某道题(自行查看)的时候,成功超时,最后只能调整高精度乘低精度的策略,将时间复杂度从 O(n×len)\mathcal O(n \times len) 优化到了 O(n)\mathcal O(n)。特殊版本 1.3.01.041.3.01.04 也从此诞生。

在这里插播一个小事情:

假设你用 1.2.01.041.2.01.04 版本去做洛谷 P1932P1932,那么你会得到这个时间复杂度:

但不过你用特殊版本 1.3.01.041.3.01.04 版本去做的话,结果是:

所以,只有在特殊情况下,再动用特殊版本。不然你可能会死的很惨

注:把 1.3.01.041.3.01.04 版本中的 vector<long long> 改成 vector<int> 即可 ACAC,但不过还是有点慢。

202420244433 日:

在这里插播一件小事情。

就是,有一些特殊的题目必须手写高精度,不可以套用模版。

如:这道题,你套用模版会取得:

但不过,你手写会:

虽然套模板可能确实很快乐,因为不用打高精度了,但不过贪心总有下场的。

所以,可以套模板,但是注意适度哦~