求四元组满足下标 (a<b<c<d),且 (p_a < p_c,\ p_b > p_d)。
总四元组总数 = 全部合法下标四元组数量 - 不满足条件的四元组数量。公式推导
先算所有满足 (a<b<c<d) 的四元组总数:(C(n,4))
不合法分为两类:
(S_1):(a<b<c<d,\ p_a \ge p_c)(不管 (p_b,p_d))
(S_2):(a<b<c<d,\ p_b \le p_d)(不管 (p_a,p_c))
两者交集 (S_{12}):(a<b<c<d,\ p_a\ge p_c \land p_b \le p_d)
根据容斥:
(\text{答案} = C(n,4) - S_1 - S_2 + S_{12})分别求三块1. (C(n,4))组合数公式:(C(n,4)=\dfrac{n(n-1)(n-2)(n-3)}{24})2. 求 (S_1):(a<b<c<d,\ p_a \ge p_c)只关心 (a<c),中间夹任意 (b(a<b<c)),后面任意 (d>c)。
对每一对 ((a,c),a<c):
若 (p_a \ge p_c),贡献数量 = b 的可选数 × d 的可选数
(cnt_b = c-a-1),(cnt_d = n-c)
(S_1 = \sum_{a<c,\ p_a\ge p_c} (c-a-1) \cdot (n-c))3. 求 (S_2):(a<b<c<d,\ p_b \le p_d)只关心 (b<d),前面任意 (a<b),中间任意 (c(b<c<d))。
对每一对 ((b,d),b<d):
若 (p_b \le p_d),贡献 = (cnt_a \cdot cnt_c)
(cnt_a = b-1),(cnt_c = d-b-1)
(S_2 = \sum_{b<d,\ p_b\le p_d} (b-1)\cdot (d-b-1))4. 求 (S_{12}):(a<b<c<d,\ p_a\ge p_c \land p_b \le p_d)固定中间两个分界点 (b,c)((b<c)):
左边选 (a \in [1,b-1]),满足 (p_a \ge p_c),记数量为 L
右边选 (d \in [c+1,n]),满足 (p_b \le p_d),记数量为 R
每组 ((b,c)) 贡献 (L\times R)
(S_{12} = \sum_{1\le b<c\le n} L(b,c) \times R(b,c))复杂度分析所有 n 总和 (\le 5000):
(S_1,S_2):(O(n^2))
(S_{12}):(O(n^2))
总复杂度 (O(\sum n^2)),(n=5000) 时 (50002=25\times106)可是原代码计算 (S_{12}) 时是三层循环:(O(n^3)),当 (n=5000) 时 (5000^3) 直接超时,1s 完全跑不动。
我们把 (S_{12}) 的 (L,R) 用预处理数组降到 (O(n^2)),整体总复杂度 (O(n^2)),总和 (\sum n^2 \le 50002=25\times106),稳过 1s。预处理思路
pre[b][c]:(a<b) 且 (p[a]\ge p[c]) 的数量(原 L)
枚举 c,从小到大扫 b 维护值域计数,(O(n^2)) 预处理。
suf[b][c]:(d>c) 且 (p[b]\le p[d]) 的数量(原 R)
枚举 b,从后往前扫 c 维护值域计数,(O(n^2)) 预处理。
复杂度总结
(S_1,S_2):(O(n^2))
预处理 pre,suf:(O(n^2))
(S_{12}):(O(n^2))
单组 (n=5000) 总操作量约 7500 万,C++ 1s 可轻松跑完。