康托展开 / lehmer编码(计算排列的字典序排名)

假设排列为 \(p_0,p_1,\ldots,p_{n-1}\) 定义

\[c_i=\#\{j>i\mid p_j<p_i\}, \]

也就是第 \(i\) 个位置后面,有多少个数比 \(p_i\) 小。
排列的字典序排名(从 \(0\) 开始)为

\[\boxed{\operatorname{rank}(p)= \sum_{i=0}^{n-1}c_i(n-1-i)!} \]

怎么证明?考虑一个排列的 \(rk\) 为比它字典序小的排列数,那枚举每一位,令它前面的数不变,从后面选一个小于它的数和它交换,剩下的乱排,便能和所有字典序小的排列一一映射了。

由于是求和形式,导致这个东西可以在很多情况下快速维护一个排列的字典序排名。
而字典序排名在标记排列,记忆化搜索之类的地方可以用到。

posted @ 2026-10-11 15:09  bjq521  阅读(2)  评论(0)    收藏  举报