在 O(nlogn) 的时间内计算三维偏序

我们设三维分别为 \(a,b,c\),以及 \(S_1=\{(i,j)|a_i<a_j\},S_2=\{(i,j)|b_i<b_j\},S_3=\{(i,j)|c_i<c_j\}\)

在这里先假设 \(a,b,c\) 都是排列,也就是不存在相同的数

那么要求的就是 \(|S_1\cap S_2\cap S_3|\)

我们考虑求出来 \(A=|S_1\cap S_2|+|S_2\cap S_3|+|S_3\cap S_1|\),这个就是三次二维偏序,\(O(n\log n)\)

然后我们发现

  • 对于一组三维偏序,我们把它算了三遍
  • 对于那些只有两维是偏序的数对,我们把它算了一遍。
  • 对于偏了一维的,贡献为 \(0\)
  • 对于偏了零维的,贡献也是 \(0\)

由对称性可以发现前两种数对的个数之和(每个只算一遍)与后面两种数对之和相等

所以「偏了三维」和「偏了两维」的数对个数恰好是所有数对个数的一半,也就是 \(\frac{n(n-1)}{2}\)

所以我们把这些都从 \(A\) 中减掉,再除以二就是三维偏序的个数了

为什么前两种数对个数之和与后两种数对个数之和相等呢

如果 \((i,j)\) 构成一个三维偏序,那么 \((j,i)\) 一定是那些三维都不偏序的数对中的一个

类似地如果 \((i,j)\) 偏了两维,那么 \((j,i)\) 肯定只偏一维

所以这个就是对称的,自然相等

posted @ 2022-06-10 23:12  云浅知处  阅读(751)  评论(0编辑  收藏  举报