#include <algorithm>
#include <random>
#include <vector>
class Solution {
public:
    long int countMerge(vector<int>& data,vector<int>& assist,int start,int end,int mid)
    {
	   //如果当前只有一个元素,逆序数记为0(递归出口)
        if(start>=end)
        {
            return 0;
        }
        else
        {
            //递归
            int midl=start+(mid-start)/2;//左边区域的逆序数
            long int leftcount=countMerge(data,assist,start,mid,midl);


            int midr=mid+1+(end-mid-1)/2;//右边区域的逆序数
            long int rightcount=countMerge(data,assist,mid+1,end,midr);



            //计算两个区域合并在一起的逆序数
            int i=start,j=mid+1;
            int tempcount=0;
            while(i<=mid)
            {
                if(data[j]<data[i]&&j<=end)
                {
                    ++tempcount;
                    ++j;
                    continue;
                }    
                leftcount+=tempcount;
                ++i;
            }



            //归并
            i=start,j=mid+1;
            int start2=start;
            while(i<=mid&&j<=end)
            {
                if(data[i]<data[j])
                {
                    assist[start2++]=data[i];
                    ++i;
                }
                else 
                {
                    assist[start2++]=data[j];
                    ++j;
                }
            }

            while(j<=end)
            {
                assist[start2++]=data[j];
                ++j;
            }
            while(i<=mid)
            {
                assist[start2++]=data[i];
                ++i;
            }
		  
            while(start<start2)//注意这里是小于,start2多向后移动了一位
            {
                data[start]=assist[start];
                ++start;
            }


			//返回逆序数
            return leftcount+rightcount;

        }



    }
    int InversePairs(vector<int> data) 
    {
        vector<int> assist;
        assist.resize(data.size()+1);//注意一定要resize()否则会溢出错误
        long int res=countMerge(data,assist,0,data.size()-1,(data.size()-1)/2);
        return res%1000000007;
    }
};

给定数组data,如果从中间分为左右两部分,如果左边逆序数为n, 右边逆序数为m,那么总逆序数为n+m+x;x为左边元素与右边元素组成逆序对的逆序数(一个序列总可以经过多次划分,分为左边或者右边元素个数为1,此时n/m为0,因此只要能计算x,就能设计递归解决这个题)。

不难发现,x的值与左右两边内部排序没有关系。如果左右两边都是升序列,那么可以在O(n)时间范围内求出x(这是因为计算左边每个元素逆序数时,右边不用回溯)。

根据以上描述,此题实际上是归并排序,只不过多加了一个计算x,归并有序序列的时间复杂度也是O(n),因此总复杂仍为O(nlogn)。