hihoCoder_二分·归并排序之逆序对
一.题目
题目1 : 二分·归并排序之逆序对
-
描写叙述
在上一回、上上回以及上上上回里我们知道Nettle在玩《艦これ》。经过了一番苦战之后。Nettle又获得了的非常多非常多的船。
这一天Nettle在检查自己的舰队列表:
我们能够看到。船默认排序是以等级为參数。但实际上一个船的火力值和等级的关系并不大,所以会存在A船比B船等级高,可是A船火力却低于B船这种情况。比方上图中77级的飞龙改二火力就小于55级的夕立改二。
如今Nettle将依照等级高低的顺序给出全部船的火力值,请你计算出一共同拥有多少对船满足上面提到的这样的情况。输入
第1行:1个整数N。N表示舰船数量, 1≤N≤100,000
第2行:N个整数。第i个数表示等级第i低的船的火力值a[i],1≤a[i]≤2^31-1。输出
第1行:一个整数。表示有多少对船满足“A船比B船等级高,可是A船火力低于B船”。
- 例子输入
-
10
1559614248 709366232 500801802 128741032 1669935692 1993231896 369000208 381379206 962247088 237855491 - 例子输出
-
27
二.解题技巧
详细做法是将两个子问题进行二分归并排序后得到的逆序数加上将子问题进行归并的时候。后面一半的元素移动的位置来得到终于的逆序数。
三.实现代码
#include <vector>
using namespace std;
long long Merge(vector<int>::iterator BeginIte, int Number)
{
if (Number < 2)
{
return 0;
}
int Mid = Number / 2;
int IndexFirst = 0;
int IndexSecond = Mid;
vector<int> TmpArray;
long long Count = 0;
int Index = 0;
while ((IndexFirst < Mid) && (IndexSecond < Number))
{
int TmpFirst = *(BeginIte + IndexFirst);
int TmpSecond = *(BeginIte + IndexSecond);
if (TmpFirst > TmpSecond)
{
TmpArray.push_back(TmpSecond);
Count += IndexSecond++ - Index++;
}
else
{
TmpArray.push_back(TmpFirst);
IndexFirst++;
Index++;
}
}
while (IndexFirst < Mid)
{
TmpArray.push_back(*(BeginIte + IndexFirst++));
}
while (IndexSecond < Number)
{
TmpArray.push_back(*(BeginIte + IndexSecond++));
}
// copy the array back
for (int Index = 0; Index < Number; Index++)
{
*(BeginIte++) = TmpArray[Index];
}
return Count;
}
long long MergeSort(vector<int>::iterator BeginIte, int Number)
{
if (Number < 2)
{
return 0;
}
int Mid = Number / 2;
long long Count = 0;
Count += MergeSort(BeginIte, Mid);
Count += MergeSort(BeginIte + Mid, Number - Mid);
Count += Merge(BeginIte, Number);
return Count;
}
int main()
{
int Number = 0;
cin >> Number;
int Index = 0;
vector<int> Array;
while (Index++ < Number)
{
int Tmp = 0;
cin >> Tmp;
Array.push_back(Tmp);
}
cout << MergeSort(Array.begin(), Number) << endl;
// for (int Index = 0; Index < Number; Index++)
// {
// cout << Array[Index] << endl;
// }
// cout << "The result is " << Count << endl;
return 0;
}
四.体会
这样的方法不仅须要进行排序的时间O(nlgn),在使用hash_table的时候,还须要O(n)的时间来推断元素在排序后的数组的下标与原来数组的下标的关系,略微有些复杂。
这样的方法主要是基于数组中的逆序对的个数等于子问题中存在的逆序对的个数加上归并过程中存在的逆序对的个数。归并过程中存在的逆序对的个数等于后面一半的元素移动到正确位置时须要移动的位数的和。
版权全部。欢迎转载,转载请注明出处,谢谢

hihoCoder_二分·归并排序之逆序对的更多相关文章
- 归并排序+归并排序求逆序对(例题P1908)
归并排序(merge sort) 顾名思义,这是一种排序算法,时间复杂度为O(nlogn),时间复杂度上和快排一样 归并排序是分治思想的应用,我们先将n个数不断地二分,最后得到n个长度为1的区间,显然 ...
- 归并排序求逆序对(poj 2299)
归并排序求逆序对 题目大意 给你多个序列,让你求出每个序列中逆序对的数量. 输入:每组数据以一个数 n 开头,以下n行,每行一个数字,代表这个序列: 输出:对于输出对应该组数据的逆序对的数量: 顺便在 ...
- 2014 HDU多校弟五场A题 【归并排序求逆序对】
这题是2Y,第一次WA贡献给了没有long long 的答案QAQ 题意不难理解,解题方法不难. 先用归并排序求出原串中逆序对的个数然后拿来减去k即可,如果答案小于0,则取0 学习了归并排序求逆序对的 ...
- 归并排序&&归并排序求逆序对
归并排序 归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用.将已有序的子序列合并,得到完全有序的序 ...
- 【BZOJ4769】超级贞鱼 归并排序求逆序对
[BZOJ4769]超级贞鱼 Description 马达加斯加贞鱼是一种神奇的双脚贞鱼,它们把自己的智慧写在脚上——每只贞鱼的左脚和右脚上各有一个数.有一天,K只贞鱼兴致来潮,排成一列,从左到右第i ...
- POJ-排序-归并排序与逆序对
排序:归并排序与逆序对 一.概念 归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用.将已有序的子序 ...
- poj2299(归并排序求逆序对)
题目链接:https://vjudge.net/problem/POJ-2299 题意:给定一个序列,每次只能交换邻近的两个元素,问要交换多少次才能使序列按升序排列. 思路:本质就是求逆序对.我们用归 ...
- 【hihocoder】三十九周:二分.归并排序之逆序对
就是用归并排序求数组中得逆序对.假设数组为a:[2 4 5],和b:[1 3],那么在这一次归并的时候逆序对这样求,belement表示当前result数组中b数组对应的元素个数,total表示逆序对 ...
- <泛> 归并排序 及 逆序对
今天写一个归并排序的模板,返回值为该序列的逆序对数 基本思路 归并排序就是利用二分的思想,将区间无限递归二分,直到当前划分区间只包含一个元素或没有元素的时候(我们认为这个序列是自动有序的),我们回溯到 ...
随机推荐
- Problem C: 线性表的基本操作
Description 线性表是一类重要的且基础的数据结构.请定义MyList类,来模拟针对线性表的插入.删除等操作: 1. 数据成员int *elements:线性表元素. 2. 数据成员int l ...
- java 以a为开头单词的词典查询示例
java中HashMap类表示为字典类,其中key,value一一对应的原则.因此是词典查询的首要工具.(HashMap字典类字面意思也可以看出~~) 程序思路: 程序开始前,应先创建一个字典文本用于 ...
- ldap数据库--ODSEE--安装
在安装之前最好查看一下服务器硬件是否满足要求,是否需要更改一些系统配置来达到使用ldap数据库的最有性能.实际使用的ldap数据库是oracle的产品,DS70即ODSEE. 安装环境:solaris ...
- 如何将FastReportOnlineDesign 灵活的应用到C/S B/S 程序当中?
一.好久没有写博客了,主要是停在这里太久了,有些事情让自己尽量不在去想,忘记不了一段难以忘怀的记忆,就让这一段美好的记忆沉没在无锡的太湖中吧!不在去想了.难以忘怀..... 二.废话不多说了,不如正题 ...
- shell的EOF用法
将命令输出的结果给一个循环处理,常用的方式如下: [root@etch171 guosong]# ls |while read line;do echo $line;done processlist ...
- 冒泡排序-Python与PHP实现版
Python实现 import random a=[random.randint(1,999) for x in range(0,33)] # 冒泡排序,python中数组是按引用传递的,会直接在原数 ...
- 最全的iOS数据存储方法
目的 项目准备运用的Core Data进行本地数据存储,本来打算只写一下Core Data的,不过既然说到了数据存储,干脆来个数据存储基础大总结!本文将对以下几个模块进行叙述. 沙盒 Plist Pr ...
- TensorFlow学习笔记(一):数据操作指南
扩充 TensorFlow tf.tile 对数据进行扩充操作 import tensorflow as tf temp = tf.tile([1,2,3],[2]) temp2 = tf.tile( ...
- SimpleMarkdown - 一款简单的Markdown编辑器
源码地址: https://github.com/zhuangZhou/SimpleMarkdown 预览地址: http://hawkzz.com:8000 作者网站:http://hawkzz.c ...
- Intellij IDEA热加载更新 IntelliJ IDEA热加载自动更新(Update classes and resources )
定义及分类 1.1 定义 在web开发环境下,所谓热部署,即在不重新部署webapp的情况下,实时将工程代码改动更新到web容器中(例如tomcat).其原理可以类比ajax的作用,即局部刷新工程资源 ...