Problem Description
Recall the problem of finding the number of inversions. As in the course, we are given a sequence of nn numbers a1,a2,⋯,an and we define an inversion to be a pair i<j such that ai>aj
We motivated the problem of counting inversions as a good measure of how different two orderings are. However, one might feel that this measure is too sensitive. Let’s call a pair a significant inversion if i<j and ai>3aj. Give an O(nlogn) algorithm to count the number of significant inversions between two orderings.
The array contains N elements (1<=N<=100,000). All elements are in the range from 1 to 1,000,000,000.
Input
The first line contains one integer N, indicating the size of the array. The second line contains N elements in the array.
- 50% test cases guarantee that N < 1000.
Output
Output a single integer which is the number of pairs of significant inversions.
Sample Inout
6
13 8 5 3 2 1
Sample Output
6
题意大题为:求当下标i < j时,满足ai>3aj条件的数值对个数。主要是使用分治算法,首先把整体拆分成两个子问题,直到不能再进行拆分,然后解决一个一个子问题。
#include<iostream>
#include<stdlib.h>
using namespace std;
int count = 0;
int min(int a, int b) {
return a < b ? a : b;
}
long long int merge(int a[], int left, int mid, int right,int b[]) {
int i = mid;
int j = right;
long long int lcount = 0;
while (i >= left && j > mid) {
if(a[i] > (long long) 3 * a[j]) { //此处很有可能造成int已经无法满足要求,因此需要定义为longlongint类型,这里是强制类型转化
lcount += j - mid;
i--;
}else{
j--;
}
}
i = mid;
j = right;
int k = 0;
while (i >= left && j > mid) {
if(a[i] > a[j]) {
b[k++] = a[i--];
}else{
b[k++] = a[j--];
}
}
while (i >= left) {
b[k++] = a[i--];
}
while (j > mid) {
b[k++] = a[j--];
}
for (i = 0; i < k; i++) {
a[right - i] = b[i];
}
return lcount;
}
long long int solve(int a[],int left, int right,int b[]) {
long long int cnt = 0;
if(right > left){
int mid = (right+left) / 2;
cnt += solve(a,left, mid,b);
cnt += solve(a,mid + 1, right,b);
cnt += merge(a,left, mid, right,b);
}
return cnt;
}
long long int InversePairs(int a[],int len)
{
int *b=new int[len];
long long int count=solve(a,0,len-1,b);
delete[] b;
return count;
}
int main() {
int n;
int i;
int a[100005];
cin>>n;
for(i = 0; i < n; i ++) {
cin >> a[i];
}
long long int count = InversePairs(a, n);
cout<<count<<endl;
}