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 }