题目描述
在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P%1000000007
输入描述:
题目保证输入的数组中没有的相同的数字
数据范围:
对于%50的数据,size<=10^4
对于%75的数据,size<=10^5
对于%100的数据,size<=2*10^5
示例1
输入
复制输出
复制
黑色数组代表原来的数组(下面用A[i]代替),红色结构代表我们的树状数组(下面用C[i]代替),发现没有,每个位置只有一个方框,令每个位置存的就是子节点的值的和,则有
- C[1] = A[1];
- C[2] = A[1] + A[2];
- C[3] = A[3];
- C[4] = A[1] + A[2] + A[3] + A[4];
- C[5] = A[5];
- C[6] = A[5] + A[6];
- C[7] = A[7];
- C[8] = A[1] + A[2] + A[3] + A[4] + A[5] + A[6] + A[7] + A[8];
class Solution { public: #define max_v 9999999 int c[max_v]; int lowbit(int x)//找到x二进制下等于1的最低位 { return x&(-x); } void update(int x,int d)//第x位置上的元素加上d { while(x<max_v) { c[x]+=d; x+=lowbit(x);//更新后面的数组值 } } int getsum(int x)//求得小于等于x的和,因为元素的值为1,代表该元素出现过,也就是求得小于等于x的元素个数 { int res=0; while(x>0) { res+=c[x]; x-=lowbit(x);//获得前面的数组值的下标 } return res; } int InversePairs(vector<int> data) { int sum=0; for(int i=0; i<data.size(); i++) { int x=data[i]; x++; //伴随着x输入序列,统计此时序列中大于x的元素的个数 //大于x的元素的个数=此时总元素个数-小于等于x的元素个数 sum=(sum%1000000007+(i-getsum(x))%1000000007)%1000000007; update(x,1); } sum%=1000000007; return sum; } };
解法2:归并排序求解逆序数
归并排序中先是划分到底,直到需要并的两个子数组中只有一个数字,这两个字序列就是分别有序的,然后两个有序序列继续合并,我们所做的处理就是在两个有序序列合并的过程中进行计算即可
现在有两个子序列,下标分别是[s,m],[m+1,t]
当前面子序列中某个元素i大于后面子序列中某个元素j时,元素i到m之间的元素肯定都是大于元素j的,因为数组是有序的,那么他们和元素j都可以组成逆序对,所以我们需要知道此时i元素到m元素之间元素的数量,其数量可以表示为m-i+1,也可以表示为j-k,k代表放入新数组中已经有序的数字,这两种表示方法都是同一个意思
归并排序求解逆序数的时间复杂度为:O(N*log N)
#include<bits/stdc++.h> #include<stdio.h> #include<memory> #include<vector> using namespace std; class Solution { public: #define max_v 2*100002 int temp[max_v]; int a[max_v]; int ans; void mer(int s,int m,int t) { int i=s; int j=m+1; int k=s; while(i<=m&&j<=t) { if(a[i]<=a[j]) { temp[k++]=a[i++]; } else { ans+=(m-i+1); //ans+=j-k;//求逆序数 ans%=1000000007; temp[k++]=a[j++]; } } while(i<=m) { temp[k++]=a[i++]; } while(j<=t) { temp[k++]=a[j++]; } } void cop(int s,int t) { for(int i=s; i<=t; i++) a[i]=temp[i]; } void megsort(int s,int t) { if(s<t) { int m=(s+t)/2; megsort(s,m); megsort(m+1,t); mer(s,m,t); cop(s,t); } } int InversePairs(vector<int> v) { int n=v.size(); for(int i=0; i<n; i++) a[i]=v[i]; megsort(0,n-1); return ans%1000000007; } };