题目描述
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数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
代码如下
//在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。
//输入一个数组,求出这个数组中的逆序对的总数P。
//例如:
//输入:1,2,3,4,5,6,7,0
//输出:7
//交换元素
void swap(int a, int b)
{
a = a + b;
b = a - b;
b = a - b;
}
//归并排序,count用来记录逆序对数
void merge(vector<int>& vecint, int lo, int mid, int hi, long& count)
{
int ln = hi - lo;
int* temp = new int[ln];
int lm = mid - lo;
int mh = hi - mid;
for(int i = mid-1, j = hi-1; (lo <= i) || ( mid <= j);)
{
if(lo <= i && mid <= j && vecint[i] > vecint[j])
{
count += j - mid + 1;
temp[--ln] = vecint[i--];
}
if(mid <= j && lo <= i && vecint[i] < vecint[j])
temp[--ln] = vecint[j--];
if(i < lo && mid <= j)
temp[--ln] = vecint[j--];
if(j < mid && lo <= i)
temp[--ln] = vecint[i--];
}
for (int i = 0; i < hi - lo; i++)
{
vecint[lo+i] = temp[i];
}
delete[] temp;
}
//归并排序,高速低空间版
void merge2(vector<int>& vecint, int lo, int mid, int hi, long& count)
{
int hb = hi - mid;
int lb = mid - lo;
int* htemp = new int[hb];
for(int i = 0; i < hb; i++) htemp[i] = vecint[mid+i];
int k = hb - 1;
for(int i = mid - 1, j = hi - 1; lo <= i || mid <= j;)
{
if((lo <= i) && ( k < 0 || htemp[k] < vecint[i]))
{
count = count + k + 1;
vecint[j--] = vecint[i--];
}
if((0 <= k) && ( i < lo || vecint[i] < htemp[k]))
vecint[j--] = htemp[k--];
}
delete[] htemp;
}
void mergeSort(vector<int>& vecint, int lo, int hi,long& count)
{
if(hi - lo < 2) return;
int mid = (hi + lo) >> 1;
mergeSort(vecint, lo, mid, count);
mergeSort(vecint, mid,hi, count);
merge2(vecint,lo,mid,hi,count);
}
int InversePairs(vector<int> data) {
if(data.empty()) return 0;
long count = 0;
int size = data.size();
mergeSort(data,0,size,count);
return count;
}
void InversePairsTest()
{
vector<int> vecint;
int a[4] = {7,5,6,4};
for(int i = 0; i < 4; i++)
vecint.push_back(a[i]);
InversePairs(vecint);
getchar();
}