置换与排列
概述
康托展开求一个排列在全部 n! 个排列中按字典序的排名:第 i 位的贡献等于其后比该位小的数的个数乘以 (n-i) 的阶乘,逐位求和即得名次;用树状数组统计后缀中更小的元素个数,可做到 O(nlogn)。逆康托展开则由给定名次反过来还原出对应排列。给出展开式与倒序枚举、边扫描边用树状数组维护的核心代码,序号从 1 起算故初值取 1。例题为洛谷 P5367 与 UVA11525。
参考资料
康托展开
康托展开 求一个排列在全部 个排列中按字典序的排名。第 位的贡献为「其后比 小的数的个数」乘以 ,求和即得名次。用树状数组统计后缀小于个数可做到 。逆康托展开则由名次还原出排列。
序号通常从 开始,所以初始令 ans=1。
ll ans=1;
for(int i=n;i>=1;i--)
{
ans=(ans+fac[n-i]*sum(a[i]))%mod;
add(a[i]);
}