首先考虑最小化逆序对数量。容易发现,对于一对 (i,j),它们是否产生逆序对是由 pi,pj 中更大的那个取正还是取负来决定的,与更小的那个无关。于是令 Li=∑j<i[pj<pi],Ri=∑j>i[pj<pi],则答案为 ∑min(Li,Ri)。假设我们现在正在计算 ansx,即 pk=x 的答案。
首先考虑 i=k 时的贡献。枚举 [1,x−1] 里的数的分布情况,可以列出式子:
(x−1)!(n−x)!i+j=x−1∑(ik−1)(jn−k)min(i,j)
接下来考虑 i=k 时的贡献。我们采用这样的想法:首先将 pk 从序列中移除,算出贡献之后再将 pk 插回原位置并且修正贡献。
移除 pk 之后的贡献相当于没有固定任何位置的 n′=n−1 的问题,我们对于每一个 i 求出 min(Li,Ri) 之和再相加:
i=1∑n−1(in−1)(i−1)!(n−1−i)!j=1∑imin(j−1,i−j)j=1∑imin(j−1,i−j)=⌊2i⌋⌊2i−1⌋
这可以 O(n) 计算。把这个式子计入每个 ansx。
考虑修正贡献。考虑当我们把 pk=x 插回原序列对一个满足 pl=y>x 的位置 l 的 min(Ll,Rl) 的影响。影响显然是,如果 k<l 且 Ll<Rl,或 k>l 且 Rl<Ll,插入之后的 min(Ll,Rl) 会比原来增加 1。
枚举 k 左右两边分别填了 i,j 个 ≤y 的数,则 y=i+j+1。如果 k<l,那么 y 在这 y 个数中位置的排名应该 <2y+1;否则应该 >2y+1。可以得到确定 y 的位置的方案有 ⌊2∣i−j∣⌋ 种。
可以发现列出的式子和 x 是没有关系的,只要求 y>x。列出式子:
(y−2)!(n−y)!i+j=y−1∑⌊2∣i−j∣⌋(ik−1)(jn−k)
我们对每个 y 求出这个,然后把它贡献到 x<y 的 ansx 上。
∣i−j∣ 可以写成 i+j−2min(i,j)。那么 ⌊2∣i−j∣⌋ 可以写成 ⌊2i+j⌋−min(i,j)。前者显然只和 i+j 有关,可以提到求和外面去。
现在就只需要对于每个 x 求出下面两个东西:
i+j=x∑(ik−1)(jn−k)i+j=x∑(ik−1)(jn−k)min(i,j)
前者显然是 (xn−1),不作解释。对于后者,我们可以直接钦定 i,j 的大小关系并且做一个分治 NTT 来解决,时间复杂度为 O(nlog2n)。代码。
然而我们有一个更高妙的做法可以做到线性。以下思路来自这篇题解。
以下令 A=k−1,B=n−k。那么我们需要对所有的 i 求这个。
j=0∑i(jA)(i−jB)min(j,i−j)
直接暴力展开。
j=0∑ij!(A−j)!(i−j)!(B−i+j)!A!B!min(j,i−j)
一个很神奇的事情是,我们可以把分母里的阶乘重新配对。
i!(A+B−i)!A!B!j=0∑ij!(i−j)!(A−j)!(B−i+j)!i!(A+B−i)!min(j,i−j)i!(A+B−i)!A!B!j=0∑i(ji)(A−jA+B−i)min(j,i−j)
可以发现后面一部分式子的组合意义就是,所有从 (0,0) 到 (A,B) 的路径与 x+y=i 的交点的横纵坐标的 min 之和,记其为 f(i)。
考虑 f(i)−f(i−1) 的意义:对于一条路径,记它与 x+y=i 的交点的横纵坐标的 min 为 p(i),则 p(i)−p(i−1)∈{0,1}。f(i)−f(i−1) 统计的就是满足 p(i)−p(i−1)=1 的路径条数。
这张图是 A=8,B=6,i=6 的情况。显然每一条从 (0,0) 到 (A,B) 的路径都会恰好经过图中一条红色或蓝色的线段。而我们需要统计的就是经过红色线段的路径。考虑分别统计经过对角线上方、下方的红色线段的路径条数,它们的流程是相同的,这里拿对角线下方来举例。
可以发现,经过对角线下方的红色线段的路径条数就是从 (0,0) 走到 (A,B−1) 且 P(3,2) 不在其上方(路径经过 P 是允许的)的路径条数。这并不能直接 O(1) 计算,但是随着 i 的增加,P 每次只会移动到相邻的位置,这对方案数的影响可以 O(1) 计算。
做一个前缀和就可以 O(n) 求出所有 f(i),于是我们就做完了。代码。