网站备案号查询系统,安徽省建设工程信息网怎么不能查询,北京网页设计公司兴田德润可信赖,wordpress本地优化加速版做道简单一点的题巩固一下
归并排序实现步骤 将整个区间 [l, r] 划分为 [l, mid] 和 [mid1, r]。 递归排序 [l, mid] 和 [mid1, r]。 将左右两个有序序列合并为一个有序序列。
题目描述
给定一个长度为 n 的整数数列#xff0c;请计算数列中的逆序对的数量。
逆序对的定义…做道简单一点的题巩固一下
归并排序实现步骤 将整个区间 [l, r] 划分为 [l, mid] 和 [mid1, r]。 递归排序 [l, mid] 和 [mid1, r]。 将左右两个有序序列合并为一个有序序列。
题目描述
给定一个长度为 n 的整数数列请计算数列中的逆序对的数量。
逆序对的定义如下对于数列的第 i 个和第 j 个元素如果满足 ij 且 a[i]a[j]则其为一个逆序对否则不是。
输入格式 输入共两行。 第一行包含整数 n表示数列的长度。 第二行包含 n 个整数表示整个数列。
输出格式 输出一个整数表示逆序对的个数。
数据范围 1≤n≤100000 数列中的元素的取值范围 [1,1e9]。
输入样例 6 2 3 4 5 6 1
输出样例 5
具体实现 实现思路 可以将所有的逆序对整体分为3大类
两个数同时出现在左半边红色 两个数同时出现在右半边绿色 一个数在左半边一个数在右半边黄色。 因此我们在归并排序的同时便要记录逆序对的个数。
红色情况时逆序对数量merge_sort(l,mid); 绿色情况时逆序对数量merge_sort(mid1,r); 黄色情况时逆序对数量先将左右两边分别变为有序序列然后双指针进行比较先选取右边序列当中第一个元素判断左边序列当中有几个元素大于他便有几个逆序对即分别选取右边序列中的每一个元素然后分别遍历左边序列当中的每个元素进行比较判断最后累加起来。
代码注解
n的最大值为100000我们计算最坏情况即数列时降序排列就一共有 n(n-1)/2 个逆序对即 5*1e9 个逆序对可能会有大于 int 值的情况因此使用 long long 进行存储。 因为左右两个均为有序数列所有当左边序列第 i 个元素大于右边序列第 j 个元素的时候左边序列 [i,mid] 都严格大于右边序列第 j 个元素即 mid-i1 个逆序对就是我们归并排序归并的过程所以每当我们输出一个 q[i]q[j] 的情况便在逆序对个数上加一个 mid-i1 。 要注意 merge_sort 的返回值类型变为 long long 否则会造成数据过多时无法AC。
实现代码
#include bits/stdc.h
using namespace std;typedef long long ll;
const int N100010;
int n;
int q[N],temp[N];
ll merge_sort(int q[],int l,int r)
{if(lr){return 0;}else{int midlr1;ll resmerge_sort(q,l,mid)merge_sort(q,mid1,r);int k0,il,jmid1;while(imidjr){if(q[i]q[j]){temp[k]q[i];k;i;}else{temp[k]q[j];k;j;resmid-i1;}}while(imid){temp[k]q[i];k;i;}while(jr){temp[k]q[j];k;j;}for(il,j0;ir;i,j){q[i]temp[j];}return res;}
}
int main()
{cinn;for(int i0;in;i){cinq[i];}cout merge_sort(q,0,n-1)endl;system(pause);return 0;
}