数组中的逆序对★★
题目描述
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007
输入描述:
题目保证输入的数组中没有的相同的数字
数据范围:
对于%50的数据,size<=10^4
对于%75的数据,size<=10^5
对于%100的数据,size<=2*10^5
示例1
输出
复制7
解题思路:
归并排序。在合并两个区间的时候,当右边的区间比左边区间的值小的时候会产生逆序,如:左区间[7 8],右区间[4 5],那么在4上就会有两个逆序,在5上也会有两个逆序。逆序大小就是左区间中比
右区间某个数大的个数,由于此时左右区间都是有序的,那么可以根据区间长度直接算出逆序个数。
int fz[1000000]; class Solution { public: const int Mod = 1000000007; int _merge(vector<int> &vct, int l, int mid, int r){ if(l >= r){ return 0; } int res = 0; int i = l; int j = mid+1; int pos = 0; while(i <= mid && j <= r){ if(vct[j] < vct[i]){ //右区间当前这个数会产生的逆序个数 res = (res + mid - i + 1) % Mod; fz[pos] = vct[j]; j++; }else{ fz[pos] = vct[i]; i++; } pos++; } while(j <= r){ fz[pos] = vct[j]; pos++; j++; } while(i <= mid){ fz[pos] = vct[i]; pos++; i++; } for( int i = 0; i < pos; i++){ //cout<<" fz[i]="<<fz[i]; vct[l] = fz[i]; l++; } return res; } int Mymerge(vector<int> &vct, int l, int r){ int res = 0; if(l < r){ int mid = (l+r)/2; int lres = Mymerge(vct, l, mid) % Mod; int rres = Mymerge(vct, mid+1, r) % Mod; res = (_merge(vct, l, mid, r) + lres + rres) % Mod; /* cout<<"l="<<l << " mid="<<mid<<" r="<< r <<" res="<<res<<endl; for(int i=l; i <= r; i++){ cout<<vct[i]<<" "; }cout<<endl; */ } return res; } int InversePairs(vector<int> data) { int res = Mymerge(data, 0, data.size()-1) % Mod; return res; } };
学学学 练练练 刷刷刷