归并排序求逆序对(poj 2299)
归并排序求逆序对
题目大意
给你多个序列,让你求出每个序列中逆序对的数量。
输入:每组数据以一个数 n 开头,以下n行,每行一个数字,代表这个序列;
输出:对于输出对应该组数据的逆序对的数量;
顺便在此吐槽一下翻译器,翻译了一顿我啥都看不懂(都怀疑自己是不是中国人了),幸亏自己还能看懂点英语啊。
这个题是机房里一位小伙伴问我我才做的,蒟蒻的我刚开始居然想要双重循环(类似于冒泡排序的方法)来做,看完数据范围之后就放弃了;
然后想到了逆序对是使用归并排序来做的,所以就自己手码了一个归并排序;;可能有的小伙伴还不知道归并排序的思想,所以看了一晚上归并排序的蒟蒻——我,就来给小伙伴们介绍一下吧!
归并排序:
nlog(n)的稳定算法(可用于求逆序对的个数)
应用方法:
二分(所以又叫二路归并)+递归;
为什么使用递归?
answer:要使用归并排序首先就要将数据分解,一直分解到每一个单位,然后就是进行合并了;
如何合并?
answer:比较a[i]和a[j]的大小(其中a[i]属于左区间,a[j]属于右区间,其实就是将左右区间合并、并排序),若a[i]<a[j],则将a[i]复制到r[k]中,然后将r和k都加1,否则将a[j]复制到r[k]中,将r,k加1,最后再将r[k]移动到a[i]中,然后继续合并;
如何求逆序对?
answer:
下面就是 归并排序求逆序对 的过程==
#include<cstdio>
using namespace std;
const int maxn=5e5+;
int a[maxn],r[maxn],n;//r[]是辅助用的;
long long ans;//ans作为全局变量记录每次逆序对的数量;
//记得ans要开long long,否则WAWAWA
void msort(int s,int t){
if(s==t) return;
int mid=(s+t)>>;//二进制下右移一位,相当于 /2 ,但是速度更快!
msort(s,mid),msort(mid+,t);//递归的体现
int i=s,j=mid+,k=s;
while(i<=mid&&j<=t)
if(a[i]<=a[j]) r[k]=a[i],i++,k++;
else r[k]=a[j],j++,k++,ans+=mid-i+;
//ans的计算是最神奇的地方,不过动动脑子,画个图啥的也是可以想出来的
while(i<=mid) r[k]=a[i],i++,k++;
while(j<=t) r[k]=a[j],j++,k++;
for(int i=s;i<=t;i++) a[i]=r[i];//每次要更新的是 a[]数组!!
}
int main(){
while(){//来一个无限的循环==
scanf("%d",&n);
if(!n) return ;//(!n相当于n==0,当然速度也是快一点的啦!)n=0就直接结束程序;
for(int i=;i<=n;i++) scanf("%d",&a[i]);
msort(,n);
printf("%lld\n",ans);
ans=;//注意:ans每次都需要清0;
}
}
poj2299
--------------------------------------------------下方高能--------------------------------------------
其实只是一个实例,解释一下ans是如何求出来的啦
a[i]↓ ←mid=4→ a[j]↓
3 4 7 9 1 5 8 10
首先将右区间的 1 取出,放到r[k]中,此时 1 是比每个a[i]中的元素都小,也就是说此时i的指针指向 a[1] 的位置,此刻得到的逆序对的数量为 4 ; r[k]= 1 ;
然后再将a[i]和a[j]比较(直到a[i]<a[j]),a[i]<a[j] 将a[i]的元素放到r[k]中; r[k]= 1 3 4;现在a[j]>a[i], i 指向 a[3] 的位置,将5 放到 r[k] 中,得到的逆序对数量为 2 ; r[k]= 1 3 4 5
以此类推,直到进行完归并排序,每次合并都会求出逆序对的数目,即 mid-i+1 ,最后每次将 ans 加上 mid-i+1即可得到最后的答案;
其实求逆序对呢,还可以用线段树,不过对于如此蒟的蒟蒻我,还是算了吧,有兴趣的小伙伴也可以自己从网上搜着看一下,蒟蒻在此就不介绍给大家了(我也不会啊)!
归并排序求逆序对(poj 2299)的更多相关文章
- 2014 HDU多校弟五场A题 【归并排序求逆序对】
这题是2Y,第一次WA贡献给了没有long long 的答案QAQ 题意不难理解,解题方法不难. 先用归并排序求出原串中逆序对的个数然后拿来减去k即可,如果答案小于0,则取0 学习了归并排序求逆序对的 ...
- 归并排序&&归并排序求逆序对
归并排序 归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,该算法是采用分治法(Divide and Conquer)的一个非常典型的应用.将已有序的子序列合并,得到完全有序的序 ...
- 【BZOJ4769】超级贞鱼 归并排序求逆序对
[BZOJ4769]超级贞鱼 Description 马达加斯加贞鱼是一种神奇的双脚贞鱼,它们把自己的智慧写在脚上——每只贞鱼的左脚和右脚上各有一个数.有一天,K只贞鱼兴致来潮,排成一列,从左到右第i ...
- poj2299(归并排序求逆序对)
题目链接:https://vjudge.net/problem/POJ-2299 题意:给定一个序列,每次只能交换邻近的两个元素,问要交换多少次才能使序列按升序排列. 思路:本质就是求逆序对.我们用归 ...
- 归并排序+归并排序求逆序对(例题P1908)
归并排序(merge sort) 顾名思义,这是一种排序算法,时间复杂度为O(nlogn),时间复杂度上和快排一样 归并排序是分治思想的应用,我们先将n个数不断地二分,最后得到n个长度为1的区间,显然 ...
- HDU 3743 Frosh Week(归并排序求逆序对)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3743 题目意思就是给你一个长为n的序列,让你求逆序对.我用的是归并排序来求的.归并排序有一个合并的过程 ...
- 浙江工商大学15年校赛I题 Inversion 【归并排序求逆序对】
Inversion Time Limit 1s Memory Limit 131072KB Judge Program Standard Ratio(Solve/Submit) 15.00%(3/20 ...
- 归并排序(归并排序求逆序对数)--16--归并排序--Leetcode面试题51.数组中的逆序对
面试题51. 数组中的逆序对 在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对.输入一个数组,求出这个数组中的逆序对的总数. 示例 1: 输入: [7,5,6,4] 输出 ...
- codeforces 414C C. Mashmokh and Reverse Operation(归并排序求逆序对)
题目链接: C. Mashmokh and Reverse Operation time limit per test 4 seconds memory limit per test 512 mega ...
随机推荐
- 一进“dos”就自动进入上次的目录
这个原来在别的地方发过,但是后来发现有bug,处理windows下带有空格的长文件夹会出错.因为原来那个帖子已经不能编辑了,所以修改后写在这里. 这里的“dos”,就是windows下的命令行窗口,所 ...
- CODING DevOps 微服务项目实战系列最后一课,周四开讲!
随着软件工程越来越复杂化,如何在 Kubernetes 集群进行灰度发布成为了生产部署的"必修课",而如何实现安全可控.自动化的灰度发布也成为了持续部署重点关注的问题.CODING ...
- 解决QT5移植报错:This application failed to start because no Qt platform plugin could be initialized
今天自己基于Pyqt5开发了一个软件,打包成exe后在自己的电脑上运行正常,在其他机器上提示: This application failed to start because no Qt platf ...
- 第6章 运行Spark SQL CLI
第6章 运行Spark SQL CLI Spark SQL CLI可以很方便的在本地运行Hive元数据服务以及从命令行执行查询任务.需要注意的是,Spark SQL CLI不能与Thrift JDBC ...
- Improved robustness of reinforcement learning policies upon conversion to spiking neuronal network platforms applied to Atari Breakout game
郑重声明:原文参见标题,如有侵权,请联系作者,将会撤销发布! arXiv:1903.11012v3 [cs.LG] 19 Aug 2019 Neural Networks, 25 November 2 ...
- HM16.0之PCM模式——xCheckIntraPCM
参考:https://blog.csdn.net/cxy19931018/article/details/79781042 1.源代码: /** Check R-D costs for a CU wi ...
- MPI中的cannon算法
Cannon算法 算法过程 假设矩阵\(A,B\)和\(C\)都可以分成\(m\times m\)块矩阵,即\(A = (A_{(ij)})_{m\times m},B = (B_{(ij)})_{m ...
- Java中的判断实例
.getClass().getName() 这是最常见的一种判断类型的方法 instanceof 用于判断 对象 是否为某个类的实例 Boolean值 各种is方法 isAnnotationPrese ...
- AlexNet实现cifar10数据集分类
import tensorflow as tf import os from matplotlib import pyplot as plt import tensorflow.keras.datas ...
- Unity添加自定义拓展方法
Shepherdog|2014-04-08 10:50|16151次浏览|Unity(373)0 通常你会发现你不能修改正在使用的那些类,无论它是基础的数据类型还是已有框架的一部分,它提供的方法让你困 ...