变进制数的运算

定义

给定 \(n, \{a_i|1\leq i\leq n, a_i\in \mathbb N^+\}, 0\leq X<\prod_{i=1}^na_i\)。则称 \(X\)\(\{a_i\}\) 下的变进制表示为一个数组 \(\{c_i|1\leq i\leq n, 0\leq c_i<a_i\}\) 满足(注意空范围的 \(\prod\) 定义为 \(1\)

\[X=\sum_{i=1}^nc_i\prod_{j=1}^{i-1}a_j \]

容易发现变进制表示是唯一的。注意,变进制数能表示的数大小有限,不妨直接定义是在 \(\bmod \prod_{i=1}^na_i\) 环境下工作。当 \(a_i=i\) 时,变进制数可以刻画排列的康托展开数。

进位

已知 \(X\) 的变进制表示,但是有一些 \(c_i\geq a_i\),你需要修正。从小到大枚举 \(i\) 逐渐往前进位使得 \(c_i<a_i\),就和高精度计算一样。最后 \(c_n\) 算完可能会溢出去,我们直接丢掉,反正我们是模意义的。

对位加

已知 \(X, Y\) 的同一变进制的表示,求 \(X+Y\) 的变进制表示。就是直接对位加,再进位。类似高精度加法。

数加

已知 \(X\) 的变进制表示与低精度整数 \(k\),求 \(X+k\) 的变进制表示。这个非常简单,正数则在 \(c_1\) 上加 \(k\),然后直接进位。负数则先取相反数(先求 \(k\) 的变进制表示再取相反数),再对位加。

相反数

已知 \(X\) 的变进制表示,求 \(-X\) 的变进制表示。你精心构造,使得 \(c_1'=a_1-c_1, c_i'=a_i-c_i-1(i>1)\) 即可。如果发现 \(c_1=0\),则你构造完了之后给它进位。

数乘

已知 \(X\) 的变进制表示与整数 \(k\),求 \(kX\) 的变进制表示。负数先取一遍相反数以防万一。完了以后你就每一个 \(c_i\) 都乘上 \(k\),然后进位。

秦九韶表示

\[X=a_1\cdots( a_{n-2}(a_{n-1}c_n+c_{n-1})+c_{n-2})\cdots+c_1 \]

不目了然,一言而喻!

获取真实值

已知 \(X\) 的变进制表示,求 \((X\bmod \prod_{i=1}^na_i)\bmod p\),其中 \(p\) 是一个低精度正整数。转秦九韶表示后从内到外计算,或者根据定义计算。

卷积

已知 \(X, Y\) 的变进制表示(变进制可以不同),求 \(XY\) 的变进制表示(以其中一个数的变进制为 \(XY\) 的变进制,不妨用 \(Y\) 的)。对 \(X\) 应用秦九韶表示,根据乘法分配律,将 \(Y\) 乘入所有 \(c_i\) 上,然后从内到外计算。形如,有一个变进制数 \(tmp=0\),然后从大到小枚举 \(i\),先对 \(tmp\) 数乘 \(a_i\),然后加上 \(c_iY\)。复杂度是 \(O(n^2)\) 的。

换进制

已知 \(X\) 在某种变进制下的表示,请换成另一种。和卷积是一样的,只不过 \(Y=1\),先转成秦九韶,然后再转到新的进制。复杂度是 \(O(n^2)\) 的。

截断

已知 \(X\)\(\{a_i|1\leq i\leq n\}\) 的变进制表示和一个 \(n_0\),求 \(X\)\(\{a_i|1\leq i\leq n_0\}\) 的变进制表示。我们直接将 \(c_i\) 截断到 \(n_0\) 就是对的。不言了然,一目而喻。


合着你这是原创科技?

所以,现在给你两个排列,你能求出它们的字典序的和、差、积对应的排列了?


更新:

变进制转定进制

已知 \(X\) 的变进制表示,要求你换成另一种定进制(所有 \(a_i\) 都为定值)的表示。观察秦九韶表示,发现一个变进制数的值可以表示为若干一次函数的复合(最后代入 \(0\)),因此,考虑分治求出这个一次函数,每次分治相当于求两个高精度定进制整数的积,可以 FFT 做到 \(O(n\log n)\),那么总的复杂度可以达到 \(O(n\log^2n)\)

定进制卷积

可以 FFT 做到 \(O(n\log n)\)

定进制转变进制

已知 \(X\) 的定进制表示,要求你换成另一种变进制表示。尝试分治,每次需要对一个高精度定进制整数整除左半部分的 \(a_i\) 的积,先做一次分治求出所有要用到的积,再做分治大力进行整除。现在的高精度技术显然可以 \(O(n\log n)\) 的整除,为了方便写代码,我们考虑使用自带这种高精度的语言(python3、pypy3、ruby、golang、haskell)实现,就可以 \(O(n\log^2n)\) 完成定进制转变进制。

再探变进制卷积

已知 \(X, Y\) 的变进制表示,求 \(XY\) 的变进制表示。将 \(X, Y\) 都转成某一定进制,在定进制下做乘法,再转换回变进制。\(O(n\log^2n)\)

posted @ 2024-09-09 16:50  caijianhong  阅读(127)  评论(0编辑  收藏  举报