求逆序数
时间限制: 2000 ms | 内存限制:65535 KB
难度: 5
- 描述
-
在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序。一个排列中逆序的总数就称为这个排列的逆序数。
现在,给你一个N个元素的序列,请你判断出它的逆序数是多少。
比如 1 3 2 的逆序数就是1。
- 输入
- 第一行输入一个整数T表示测试数据的组数(1<=T<=5) 每组测试数据的每一行是一个整数N表示数列中共有N个元素(2〈=N〈=1000000) 随后的一行共有N个整数Ai(0<=Ai<1000000000),表示数列中的所有元素。 数据保证在多组测试数据中,多于10万个数的测试数据最多只有一组。 输出
- 输出该数列的逆序数 样例输入
-
221 131 3 2
样例输出 -
01 归并排序执行过程: 1、执行归并排序函数时,把全部的数字一分为二,继续递归调用函数自身,左一半右一半的划分开,直到每一份里只有一个元素为止,停止划分。 2、把划分开的元素按照大小顺序排列,先 1 1,合并为个数为 2 的数组,再把 2 2 按顺序大小要求合并成个数为 4 的数组,依次进行把所有元素按大小排序 两两合并时两序列均已是有序序列 如: 4 1 3 10 7 3 5 0 4 1 3 10 7 3 5 0 4 1 3 10 7 3 5 0 4 1 3 10 7 3 5 0 //每一组个数为 1 结束 合并: 1 4 3 10 3 7 0 5 1 3 4 10 0 3 5 7 最后结果: 0 1 3 3 4 5 7 10 本题利用归并时比较大小条件,因为两序列合并时都已经是有序的,所以一旦遇到前一个序列的a比后一个序列中的一个值大,那么前一个序列数的值a以后的数(包括a)都比后序列的值大,所以sum += (p3-s1+1); sum用long long. 代码如下:
1 2 //归并排序 3 4 #include
5 #include 6 long long sum = 0; 7 void mergesort(int a[],int ,int ); 8 int main() 9 {10 int a[1000300];11 int T,n,i;12 scanf("%d",&T);13 while(T--)14 {15 sum = 0;16 scanf("%d",&n);17 for(i=0;i <= p2;i++)//把排好序的数组存回原来的地方53 a[i] = temp[j++];54 55 delete temp;//记得释放指针56 }57 void mergesort(int a[],int left,int right)58 {59 //先一直拆分左边,知道拆分的只剩下一个元素为止,然后以一个元素为对称,右边也只有一个元素,然后合并两个元素60 //一直这样向上合并,先1 1合并,然后2 2 合并 4 4..8 8..16 16...知道所有元素都已经合并完成61 //带合并的两列数字都已经是有序的62 int mid;63 if(left < right)64 {65 mid = (left+right)/2;66 mergesort(a,left,mid);//左拆分67 mergesort(a,mid+1,right);//右拆分68 69 merge(a,left,mid,mid+1,right);//合并70 }71 }72