剪开黑夜

In the twilight of every early morning

导航

OpenJudge 求重要逆序对数

Posted on 2018-12-20 12:58  剪开黑夜  阅读(528)  评论(0编辑  收藏  举报

https://blog.csdn.net/mrvector/article/details/81090165

【题解】

         方法与求逆序对的个数类似,用归并排序分治求解。不同之处在于添加了一个虚拟指针pointer。

【代码】

 1 #include <iostream>
 2 using namespace std;
 3 #define maxn 200005
 4 
 5 int s[maxn], temp[maxn];
 6 long long ans;
 7 
 8 void Merge(int left, int right, int mid)
 9 {
10     int i = left, j = mid + 1, k = left;
11     int pointer = left;
12     while (i <= mid && j <= right) {
13         if (s[i] > s[j]) {
14             temp[k++] = s[j];
15             while (pointer <= mid && s[pointer] <= 2 * s[j])
16                 pointer++;
17             if (pointer < mid + 1)
18                 ans += mid - pointer + 1;
19             j++;
20         }
21         else {
22             temp[k++] = s[i];
23             i++;
24         }
25     }
26     while (i <= mid) 
27         temp[k++] = s[i++];
28     while (j <= right)
29         temp[k++] = s[j++];
30     for (int i = left; i <= right; i++)
31         s[i] = temp[i];
32 }
33 
34 void MergeSort(int left, int right)
35 {
36     int mid = (left + right) >> 1;
37     if (left < right) {
38         MergeSort(left, mid);
39         MergeSort(mid + 1, right);
40         Merge(left, right, mid);
41     }
42 }
43 
44 int main()
45 {
46     int N;
47     cin >> N;
48     for (int i = 0; i < N; i++)
49         cin >> s[i];
50     MergeSort(0, N - 1);
51     cout << ans << endl;
52     //system("pause");
53     return 0;
54 }