题意:
https://acm.sjtu.edu.cn/OnlineJudge/problem/1219
思路:
在经典的归并排序求逆序数对算法基础上稍作修改。
实现:
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 using namespace std; 5 const int MAXN = 200005; 6 int n, a[MAXN], tmp[MAXN]; 7 long long cnt = 0; 8 9 void mergeSort(int * a, int left, int right, int * tmp) 10 { 11 if (left >= right) 12 return; 13 int mid = (left + right) / 2; 14 mergeSort(a, left, mid, tmp); 15 mergeSort(a, mid + 1, right, tmp); 16 int x = left; 17 int y = mid + 1; 18 int start = left; 19 while (x <= mid && y <= right) 20 { 21 if (a[x] < a[y]) 22 { 23 tmp[start++] = a[x++]; 24 } 25 else 26 { 27 int pos = upper_bound(a + x, a + mid + 1, 2 * a[y]) - a; 28 cnt += mid - pos + 1; 29 tmp[start++] = a[y++]; 30 } 31 } 32 while(x <= mid) 33 { 34 tmp[start++] = a[x++]; 35 } 36 while(y <= right) 37 { 38 tmp[start++] = a[y++]; 39 } 40 for (int i = left; i <= right; i++) 41 { 42 a[i] = tmp[i]; 43 } 44 } 45 int main() 46 { 47 scanf("%d", &n); 48 for (int i = 0; i < n; i++) 49 { 50 scanf("%d", &a[i]); 51 } 52 mergeSort(a, 0, n - 1, tmp); 53 cout << cnt << endl; 54 return 0; 55 }