#3266. 逆序对

    ID: 3266 Type: Default 1000ms 256MiB Tried: 0 Accepted: 0 Difficulty: (None) Uploaded By: Tags>数据结构树状数组其他离散化逆序对CSP-S 模拟

逆序对

题目描述

一次编程比赛后,nn 名选手排成一排,第 ii 名选手(从左到右)的得分是整数 aia_i。

教练想知道队伍有多"乱"。他定义逆序对为满足下面两个条件的有序下标对 (i,j)(i, j):

  • i<ji < j(ii 在 jj 的左边);
  • ai>aja_i > a_j(左边这位选手的得分严格大于右边那位)。

请你求出队伍中逆序对的总数。

输入格式

第一行一个整数 nn。

第二行 nn 个整数 a1,a2,…,ana_1, a_2, \ldots, a_n,相邻两个整数之间用一个空格隔开。

输出格式

一行一个整数,表示逆序对的总数。

3
3 1 2
2
5
5 4 3 2 1
10
4
2 2 1 1
4

数据范围与提示

【样例 1 解释】

得分序列是 3,1,23, 1, 2。逐个检查下标对:

  • (1,2)(1,2):3>13 > 1,是逆序对;
  • (1,3)(1,3):3>23 > 2,是逆序对;
  • (2,3)(2,3):1<21 < 2,不是。

共有 22 个逆序对,输出 2。

【样例 2 解释】

序列严格递减,任何一对 (i,j)(i, j)(i<ji < j)都满足 ai>aja_i > a_j,共有 5×42=10\frac{5\times 4}{2} = 10 个逆序对。

【样例 3 解释】

序列是 2,2,1,12, 2, 1, 1。注意相等不算逆序对,所以 (1,2)(1,2) 与 (3,4)(3,4) 都不是逆序对;真正构成逆序对的是 (1,3),(1,4),(2,3),(2,4)(1,3),(1,4),(2,3),(2,4),共 44 个,输出 4。

【数据范围】

对于所有测试数据,保证:

  • 1≤n≤2×1051 \le n \le 2\times 10^5;
  • −109≤ai≤109-10^9 \le a_i \le 10^9。

注意:逆序对总数最多为 n(n−1)2=19999900000\frac{n(n-1)}{2} = 19999900000,远超 int 的表示范围,计数的变量请使用 long long。

提示:从左到右扫描,扫到 aja_j 时它贡献的逆序对数是"已经出现过的、比它大的元素个数"。由于值域高达 10910^9,先把所有取值离散化(排序去重后换成排名),再用树状数组维护"每个排名出现过多少次",单次查询与修改都是 O(log⁡n)O(\log n)。用归并排序统计逆序对同样可行。

测试点编号 n≤n \le 特殊性质
11 无
22 22 A
33 B
44 33 无
55 B
66 1010 无
77 100100
88 A
99 10001000 B
1010 无
1111 C
1212 20002000 无
1313 50005000
1414 D
1515 2000020000 无
1616 B
1717 2×1052\times 10^5 无
1818 B
1919 C
2020 D
  • 特殊性质 A:序列严格递增(a1<a2<⋯<ana_1 < a_2 < \cdots < a_n),此时逆序对个数一定是 00。
  • 特殊性质 B:序列严格递减,此时逆序对个数取到最大值 n(n−1)2\frac{n(n-1)}{2}。
  • 特殊性质 C:所有 aia_i 相等,此时一个逆序对也没有(相等不算逆序对)。
  • 特殊性质 D:值域很小(0≤ai≤100 \le a_i \le 10),出现大量相等元素,可以不离散化而直接用桶。