摘要: 转自: http://huangwei.host7.meyu.net/?p=24题意:给定序列,求出[s,t]区间内第k小的数字。解法:线段树+归并排序+二分枚举Whu回来后,开始好好看了下其余题目,感觉区间k大数应该有经典算法,问了下linle才知道poj上有原题,实在郁闷。比赛时也想到了线段树,但是没考虑到开另一个空间去保存排序后的值,所以一直没法打开思路。(1)用线段树来表示区间,构造线段树O(NlogN),这样能在O(logN)时间内确定区间的最大值。(2)另外保存了排序后的值后,那给定一个值,可以在区间内查找从而得出该值排序后的位置,这里可以用二分查找,复杂度又乘上了O(logN)。 阅读全文
posted @ 2012-08-01 12:28 何解一直犯相同错误? 阅读(149) 评论(0) 推荐(0) 编辑
摘要: 题意:给出一数组a,然后要求查询a[i..j]的第k大的数。算法:继续我的学习数据结构的步伐,之前学习了后缀数组,今天继而学习另一个有用的统计工具,归并树。实际上归并树,就是把归并排序的过程记录下来。也算是一个线段树吧,但是节点的记录了该区间[i,j]的排序后的结果。先不要考虑空间复杂度,如果可以在每个节点放有该区间排序后的结果,那么我们把查询的区间去查找,就是像线段树的查找一样,要查询的数k在各个区间中有多少个数小于k,然后相加起来,这样,便可以得到该区间中,k这个数有多少个数小于k。因此我们把数组排序后二分,便可以找到结果。归并树:刚才考虑到线段树不可能每个节点都存放排序后的结果,因为在每 阅读全文
posted @ 2012-08-01 12:26 何解一直犯相同错误? 阅读(186) 评论(0) 推荐(0) 编辑
摘要: 【题目描述】有n个数字排成一列,有m个询问,格式为:left right k 即问在区间[left,right]第k大的数据为多少?建图: 建树的过程比较简单,对于区间[l,r],首先通过对原数组的排序找到这个区间的中位数a[mid],小于a[mid]的数划入它的左子树[l,mid-1],大于它的划入右子树[mid,r]。 同时,对于第i个数a[i],记录在[l,i]区间内有多少数被划入左子树。最后,对它的左子树区间[l,mid-1]和右子树区间[mid,r]递归的继续建树就可以了。 建树的时候要注意,对于被分到同一子树的元素,元素间的相对位置不能改变。查找的过程中主要问题就是确定将要查找的区 阅读全文
posted @ 2012-08-01 12:24 何解一直犯相同错误? 阅读(142) 评论(0) 推荐(0) 编辑
摘要: 二分查找 + 线段树这里线段树就是query()函数。不懂线段树的童鞋先不要急,你们姑且把它看成是二分就行了。二分在这道题中是很重要的思想. 先初始化, b[]数组排好序就是a[0][], x=0, y=n-1. 我们先取中间的数num=a[0][mid], where mid=(x+y)/2 来测试, 我们得到num在b[lef...rig]中的排在[rankL, rankR)的位置(注意是左闭右开区间). 如果A. rankL<=k && k<rankR 那么数num就是所求的数; 否则根据下面更新x或y不断迭代.B.k >= rankR 那么num较小, 阅读全文
posted @ 2012-08-01 12:24 何解一直犯相同错误? 阅读(124) 评论(0) 推荐(0) 编辑