题目描述
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007
输入描述:
题目保证输入的数组中没有的相同的数字
数据范围:
对于%50的数据,size<=10^4
对于%75的数据,size<=10^5
对于%100的数据,size<=2*10^5
示例1
输入
1,2,3,4,5,6,7,0
输出
7
class Solution {
public:
long long InversePairsCore(vector<int> &data,vector<int>©,int start,int end)
{
if(start==end)
{
copy[start]=data[start];
return 0;
}
int length = (end-start)/2;
long long left = InversePairsCore(copy,data,start,start+length);
long long right = InversePairsCore(copy,data,start+length+1,end);
int i = start + length;
int j = end;
int indexCopy = end;
long long count=0;
while(i>=start&&j>=start+length+1)
{
if(data[i]>data[j])
{
copy[indexCopy--]=data[i--];
count+=j-start-length;
}
else
{
copy[indexCopy--]=data[j--];
}
}
for(;i>=start;--i)
copy[indexCopy--] = data[i];
for(;j>=start+length+1;--j)
copy[indexCopy--] = data[j];
return left+right+count;
}
int InversePairs(vector<int> data) {
int length = data.size();
if(length<=0)
return 0;
vector<int> copy;
for(int i=0;i<length;i++)
copy.push_back(data[i]);
long long count = InversePairsCore(data,copy,0,length-1);
copy.clear();
return count%1000000007;
}
};
有种更好理解的思路:
# include <iostream>
#include <stdio.h>
using namespace std;
typedef long long ll;
int n, arr[100010], tmp[100010];
//归并排序,过程中 统计逆序数
ll merge(int start, int mid, int end){
ll cnt = 0;
int i = start, j = mid+1, k = start;
while( i<=mid && j<= end){
//从大到小排序
if(arr[i] > arr[j]){
cnt += (end-j+1); //右面剩下的都是逆序
tmp[k++] = arr[i++];
}else{
tmp[k++] = arr[j++];
}
}
while(i<=mid) tmp[k++] = arr[i++];
while(j<=end) tmp[k++] = arr[j++];
for(int i=start; i<=end; i++) arr[i] = tmp[i];
return cnt;
}
ll inversePairs(int start, int end){
ll cnt = 0;
if(start < end){
int mid = (start + end)/2;
cnt += inversePairs(start, mid); //左半部分 逆序对数量
cnt += inversePairs(mid+1, end); //右半部分
cnt += merge(start, mid, end); //合并两部分,并计算数量
}
return cnt;
}
int main() {
//freopen("in.txt", "r", stdin);
while( scanf("%d", &n) != EOF){
for(int i=0; i<n; i++) scanf("%d", &arr[i]);
ll ans = inversePairs(0, n-1);
printf("%lld\n",ans);
}
return 0;
}