【专题】线性判定排列逆序数的奇偶性

排列逆序数的奇偶性是一个十分常见的属性。不同于直接求逆序数,由于排列的性质,这玩意是可以 O(n) 直接求解的。为了完成这一点,引入如下基本结论:

  1. 排列两元素对换,逆序数奇偶性改变。
  2. 排列的逆序数同余 n#环。

第一点,在大多数线性代数教材中都有所提及。

第二点中的 “环” 的构造方式:按下标 ipi 连边,或者说,两排列之间连边,必形成若干环(这是因为每个数都出现一次,对应的入/出度数为 1)。

定义排列的复合 (fg)xx 变为 fgx,下证

parity(fg)=parity(f)+parity(g)

f 经过 swap(i,j) 后,变为 f,其奇偶性变为 parity(f)+1。可表示为 fg=f,其中排列 f,g 仅有 (i,j) 两点顺序不同。这过程可以归纳,得到上述结论不难。

为啥是这个数?考虑 swap(i,j) 在从 ipi 的图上是什么含义?注意到如果交换环上两点,将会产生一个自环,环的大小会减一。用上面的话来说,对于环 ci{C}kswap(i,j) 实为 fc1c2ck,而在这个环上的奇偶变化为 k1,将所有环的贡献相加就得到:

k11+k21++kt1=n#


这个结论十分有用。

有点记不清了但至少 ABC 出过三四次了,每次看蒋老师代码都觉得“哦,这tm我学过啊”真是十分常见的结论。下附代码:

bool parity = n & 1;
for (int i : p) if (~i) {
    for (int j = i; ~j; ) {
        std::tie(j, p[j]) = std::tuple{p[j], -1};
    }
    parity ^= 1;
}

  1. 参考 CodeForces Blog: https://codeforces.com/blog/entry/97849 ↩︎

作者:patricky

出处:https://www.cnblogs.com/patricky/p/linear-permutation-parity.html

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   PatrickyTau  阅读(883)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示
more_horiz
keyboard_arrow_up light_mode palette
选择主题