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,⋯,ana1,a2,⋯,an, and we define an inversion to be a pair i<ji
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<ji
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 解法:标准的逆序对数上加了一点变化,ai>aj*3 才算做逆序对数,因此在merge之前扫一遍就行计算逆序对的数量,然后加起来,将merge与计算逆序对数分开。 代码:
#include<algorithm>
using namespace std;
long long t[100010];
long long a[100010];
long long sum=0;
void solve(int l,int r)
{
//printf("%d %d\n",l,r);
if(r-l<2)
{
if(r - l == 1 && a[l] > 3 * a[r])
sum++;
if(r-l == 1 && a[l] > a[r]){
swap(a[l], a[r]);
}
return ;
}
int m = (l + r) >> 1;
solve(l , m);
solve(m+1 , r);
int now = m-l+1;
int sz = l, sy = m+1;
int i = m, j = r;
while (i >= l && j > m) {
if(a[i] > (long long) 3 * a[j]) {
sum += j - m;
i--;
}else{
j--;
}
}
for(int i = 0; i < r - l + 1; i++)
{
if(sz <= m && sy <= r)
{
if(a[sz] > a[sy]){
t[i] = a[sy];
sy++;
//sum += now;
}
else
{
t[i] = a[sz];
sz++;
now--;
}
}
else if(sz == m+1)
{
while(sy <= r)
{
t[i] = a[sy];
sy++; i++;
}
}
else
{
while(sz <= m)
{
t[i] = a[sz];
sz++;
i++;
}
}
}
for(int i= l ; i <= r; i++)
a[i] = t[i-l];
}
int main()
{
int n;
scanf("%d",&n);
for(int i = 1; i <=n; i++)
scanf("%lld",&a[i]);
solve(1,n);
printf("%lld\n",sum);
return 0;
}