在 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)\) 肯定只偏一维
所以这个就是对称的,自然相等