定义
给定 \(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\))
容易发现变进制表示是唯一的。注意,变进制数能表示的数大小有限,不妨直接定义是在 \(\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\),然后直接进位。负数则先取相反数,再对位加。
相反数
已知 \(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\) 的变进制表示,求 \((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\) 就是对的,不言而喻,一目了然。