康拓展开
康拓展开用于求一个排列在所有排列中的排名。
也常用与哈希。
\(rank=\sum_{i=1}^{n}sum_{a_i}(n-i)!\),其中 \(sum_{a_i}\) 表示在 \(i\) 之后的,且值比 \(a_i\) 小的数的个数。
对于排名,一位一位进行考虑。
设当前考虑到第 \(i\) 位,比 \(a_i\) 小的数有 \(sum\) 个,即只有在 \(i\) 这一位放这 \(sum\) 个数得到的排名才比给定排列的排名小,这之后,第 \(i\) 位之后的数就可以随便进行组合,即剩下的数的排列,\((n-i)!\).
注意这计算的是排名小于当前排列的排列的个数,所以初始排名为 \(1\),使用树状数组进行优化。
int ans=1;
for(int i=1;i<=n;i++){
bit.add(a[i],-1);
(ans+=bit.ask(a[i])*fac[n-i]%mod)%=mod;
}