欢迎访问我的pat顶级题解目录哦
题目描述
算法设计
可以利用树状数组来解决这个问题。
由于n不会超过 1 0 3 10^3 103 ,因此我们可以开辟一个长1005的树状数组c。设计getSum(x)函数表示1到x这些数字在序列中出现次数之和。设计update函数用于更新数字出现次数。
首先我们要明白如果我们定义A[i]
左侧比A[i]
大的数字个数为S[i]
,那么对于序列A[i]~A[j]
,其逆序数为 ∑ k = i j S k \sum _{k=i}^j S_k ∑k=ijSk。我们可以通过树状数组求解A[i]
左侧比A[i]
大的数字个数,进而可以求解一个序列的逆序数。建立一个二维数组ans
,存储每个区间的逆序数,即ans[i][j]
表示序列A[i]~A[j]
的逆序个数。
接下来,假设我们求得序列A[i]~A[j]
的逆序数为ans[i][j]
,由于序列A[i]~A[j]
任选两个数的情况数为 C j − i + 1 2 = ( j − i + 1 ) ( j − i ) 2 C_{j-i+1}^2=\frac {(j-i+1)(j-i)} 2 Cj−i+12=