nyoj 117 求逆序数 (归并(merge)排序)
求逆序数
- 描述
-
在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序。一个排列中逆序的总数就称为这个排列的逆序数。
现在,给你一个N个元素的序列,请你判断出它的逆序数是多少。
比如 1 3 2 的逆序数就是1。
- 输入
- 第一行输入一个整数T表示测试数据的组数(1<=T<=5)
每组测试数据的每一行是一个整数N表示数列中共有N个元素(2〈=N〈=1000000)
随后的一行共有N个整数Ai(0<=Ai<1000000000),表示数列中的所有元素。数据保证在多组测试数据中,多于10万个数的测试数据最多只有一组。
- 输出
- 输出该数列的逆序数
- 样例输入
-
2
2
1 1
3
1 3 2 - 样例输出
-
0
1 分析:1 归并排序(是稳定排序,只比快速排序慢一点):建立在归并操作上的一种排序,是指将有序的子序列进行合并,得到完全有序的序列;
2 及就是先使每个子序列有序,在使子序列段间有序。
3
4 此题,所求及就是从小到大排序过程,较小元素向前移动的步数,冒泡排序(算法复杂度O(n^2))算法模板:
void merge_achieve(int begin_pos, int mid_pos, int end_pos)
{
int i = being_pos, j = mid_pos + , k = end_pos;
while(i <= mid_pos && j <= end_pos)
{
if (A[i] <= A[j]) // 升序排列
temp[k ++] = A[i ++];
else
{
temp[k ++] = A[j ++];
ans += mid - i + ;
}
}
while (i <= mid_pos) tmep[k ++] = A[i ++];
while (j <= end_pos) temp[k ++] = A[j ++]; for (int ii = begin_pos; ii <= end_pos; ++ ii)
A[ii] = temp[ii];
} void merge_sort(int begin_pos, int end_pos)
{
int mid_pos;
if (begin_pos < end_pos) // 等于的情况,就集中到一个点上,不用比较大小
{
mid_pos = (begin_pos + end_pos) / ;
merge_sort(begin_pos ,mid_pos);
merge_sort(mid_pos + , end_pos);
merge_achieve(begin_pos, mid_pos, end_pos);
}
}C/C++代码实现(AC):
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <stack>
#include <map>
#include <queue> using namespace std;
const int MAXN = 1e6 + ;
int A[MAXN], temp[MAXN], n;
long long ans; void merge_achieve(int begin_pos, int mid_pos, int end_pos)
{
int i = begin_pos, j = mid_pos + , k = begin_pos;
while(i <= mid_pos && j <= end_pos)
{
if (A[i] <= A[j])
temp[k ++] = A[i ++];
else
{
temp[k ++] = A[j ++];
ans += mid_pos - i + ;
}
}
while(i <= mid_pos) temp[k ++] = A[i ++];
while(j <= end_pos) temp[k ++] = A[j ++];
for (int ii = begin_pos; ii <= end_pos; ++ ii)
A[ii] = temp[ii];
} void merge_sort(int begin_pos, int end_pos)
{
if (begin_pos < end_pos)
{
int mid_pos = (begin_pos + end_pos) / ;
merge_sort(begin_pos, mid_pos);
merge_sort(mid_pos + , end_pos);
merge_achieve(begin_pos, mid_pos, end_pos);
}
} int main ()
{
int T;
scanf ("%d", &T);
while (T --)
{
ans = ;
scanf("%d", &n);
for(int i = ; i < n; ++ i)
scanf("%d", &A[i]);
merge_sort(, n - ); // this is [0, n-1], bug one
printf("%lld\n", ans);
}
return ;
}
nyoj 117 求逆序数 (归并(merge)排序)的更多相关文章
- 归并排序及应用 (nyoj 117 求逆序数)
求逆序数 时间限制:2000 ms | 内存限制:65535 KB 难度:5 描述 在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序.一个排列中 ...
- NYOJ 117 求逆序数 (树状数组)
题目链接 描述 在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序.一个排列中逆序的总数就称为这个排列的逆序数. 现在,给你一个N个元素的序列,请你判断出 ...
- SDUT 3402 数据结构实验之排序五:归并求逆序数
数据结构实验之排序五:归并求逆序数 Time Limit: 40MS Memory Limit: 65536KB Submit Statistic Problem Description 对于数列a1 ...
- SDUT-3402_数据结构实验之排序五:归并求逆序数
数据结构实验之排序五:归并求逆序数 Time Limit: 50 ms Memory Limit: 65536 KiB Problem Description 对于数列a1,a2,a3-中的任意两个数 ...
- 51 Nod 1107 斜率小于0的连线数量 (转换为归并求逆序数或者直接树状数组,超级详细题解!!!)
1107 斜率小于0的连线数量 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 二维平面上N个点之间共有C(n,2)条连线.求这C(n,2)条线中斜率小于0的线 ...
- 2014多校第五场1001 || HDU 4911 Inversion (归并求逆序数)
题目链接 题意 : 给你一个数列,可以随意交换两相邻元素,交换次数不超过k次,让你找出i < j 且ai > aj的(i,j)的对数最小是多少对. 思路 : 一开始想的很多,各种都想了,后 ...
- POJ 2299 Ultra-QuickSort 求逆序数 (归并或者数状数组)此题为树状数组入门题!!!
Ultra-QuickSort Time Limit: 7000MS Memory Limit: 65536K Total Submissions: 70674 Accepted: 26538 ...
- hiho一下 第三十九周 归并排序求逆序数
题目链接:http://hihocoder.com/contest/hiho39/problem/1 ,归并排序求逆序数. 其实这道题也是可以用树状数组来做的,不过数据都比较大,所以要离散化预处理一下 ...
- [CF 351B]Jeff and Furik[归并排序求逆序数]
题意: 两人游戏, J先走. 给出一个1~n的排列, J选择一对相邻数[题意!!~囧], 交换. F接着走, 扔一硬币, 若正面朝上, 随机选择一对降序排列的相邻数, 交换. 若反面朝上, 随机选择一 ...
随机推荐
- [51nod1670] 打怪兽
lyk在玩一个叫做“打怪兽”的游戏.游戏的规则是这样的.lyk一开始会有一个初始的能量值.每次遇到一个怪兽,若lyk的能量值>=怪兽的能量值,那么怪兽将会被打败,lyk的能量值增加1,否则lyk ...
- [CF467D] Fedor and Essay
After you had helped Fedor to find friends in the «Call of Soldiers 3» game, he stopped studying com ...
- nginx::certbot制作免费证书
环境 Ubuntu8.04apt-get update apt-get install software-properties-common add-apt-repository ppa:certbo ...
- Spring Boot Mail 实现邮件发送
此 demo 主要演示了 Spring Boot 如何整合邮件功能,包括发送简单文本邮件. 邮件服务在开发中非常常见,比如用邮件注册账号.邮件作为找回密码的途径.用于订阅内容定期邮件推送等等,下面就简 ...
- day19作业
1.什么是对象?什么是类? 对象是特征和功能的结合体 类是一系列对象相同的特征和技能的集合体 2.绑定方法的有什么特点 绑定方式是由对象来调用类内部的函数,特点是会把对象当作第一个参数传入 ...
- docker 概念简介、简单入门
1.docker 简介 Docker 是一个开源项目,这个项目旨在通过把应用程序打包为可移植的.自给自足的容器(引用语) DocKer一次构建可放在任何地方就可以运行,不需要进行任何改变DocKer ...
- tomcat 7.0 免安装版配置
转载请注明出处,欢迎邮件交流:1057449102@qq.com 注意:tomcat 运行是依赖jdk的,前提是要安装了jdk,配置好. 1.把下载好的 apache-tomcat-7.0.85.zi ...
- 死磕 java线程系列之线程池深入解析——定时任务执行流程
(手机横屏看源码更方便) 注:java源码分析部分如无特殊说明均基于 java8 版本. 注:本文基于ScheduledThreadPoolExecutor定时线程池类. 简介 前面我们一起学习了普通 ...
- 【并发编程】Volatile原理和使用场景解析
目录 一个简单列子 Java内存模型 缓存不一致问题 并发编程中的"三性" 使用volatile来解决共享变量可见性 volatile和指令重排(有序性) volatile和原子性 ...
- 为什么磁盘慢会导致Linux负载飙升?
一.CPU利用率和负载率的区别 这里要区别CPU负载和CPU利用率,它们是不同的两个概念,但它们的信息可以在同一个top命令中进行显示.CPU利用率显示的是程序在运行期间实时占用的CPU百分比,这是对 ...