划分树

昨天的杭电多校联合训练热身赛的一道题,求区间的中位数,快排会超时,划分树的模版题。。 

 

划分树是一种基于线段树的数据结构。主要用于快速求出(在log(n)的时间复杂度内)序列区间的第k大值 。

划分树和归并树都是用线段树作为辅助的,原理是基于快排 和归并排序 的。

划分树的建树过程基本就是模拟快排过程,取一个已经排过序的区间中值,然后把小于中值的点放左边,大于的放右边。并且记录d层第i个数之前(包括i)小于中值的放在左边的数。具体看下面代码注释。


查找其实是关键,因为再因查找[l,r]需要到某一点的左右孩子时需要把[l,r]更新。具体分如下几种情况讨论:
假设要在区间[l,r]中查找第k大元素,t为当前节点,lch,rch为左右孩子,left,mid为节点t左边界和中间点。
1、sum[r]-sum[l-1]>=k,查找lch[t],区间对应为[ left+sum[l-1] , left+sum[r]-1 ]
2、sum[r]-sum[l-1]<k,查找rch[t],区间对应为[ mid+1+l-left-sum[l-1] , mid+1+r-left-sum[r] ]

上面两个关系在纸上可以推出来,对着上图更容易理解关系式


POJ 2104 划分树模板    http://poj.org/problem?id=2104


 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 using namespace std;
 5 #define N 100005
 6 int a[N], as[N];//原数组,排序后数组
 7 int n, m;
 8 int sum[20][N];//记录第i层的1~j划分到左子树的元素个数(包括j)
 9 int tree[20][N];//记录第i层元素序列
10 void build(int c, int l, int r){
11     int i, mid = (l + r) >> 1, lm = mid - l + 1, lp = l, rp = mid + 1;
12     for (i = l; i <= mid; i++){
13         if (as[i] < as[mid]){
14             lm--;//先假设左边的(mid - l + 1)个数都等于as[mid],然后把实际上小于as[mid]的减去
15         }
16     }
17     for (i = l; i <= r; i++){
18         if (i == l){
19             sum[c][i] = 0;//sum[i]表示[l, i]内有多少个数分到左边,用DP来维护
20         }else{
21             sum[c][i] = sum[c][i - 1];
22         }
23         if (tree[c][i] == as[mid]){
24             if (lm){
25                 lm--;
26                 sum[c][i]++;
27                 tree[c + 1][lp++] = tree[c][i];
28             }else
29                 tree[c + 1][rp++] = tree[c][i];
30         } else if (tree[c][i] < as[mid]){
31             sum[c][i]++;
32             tree[c + 1][lp++] = tree[c][i];
33         } else{
34             tree[c + 1][rp++] = tree[c][i];
35         }
36     }
37     if (l == r)return;
38     build(c + 1, l, mid);
39     build(c + 1, mid + 1, r);
40 }
41 int query(int c, int l, int r, int ql, int qr, int k){
42     int s;//[l, ql)内将被划分到左子树的元素数目
43     int ss;//[ql, qr]内将被划分到左子树的元素数目
44     int mid = (l + r) >> 1;
45     if (l == r){
46         return tree[c][l];
47     }
48     if (l == ql){//这里要特殊处理!
49     s = 0;
50     ss = sum[c][qr];
51     }else{
52         s = sum[c][ql - 1];
53         ss = sum[c][qr] - s;
54     }//假设要在区间[l,r]中查找第k大元素,t为当前节点,lch,rch为左右孩子,left,mid为节点t左边界和中间点。
55     if (k <= ss){//sum[r]-sum[l-1]>=k,查找lch[t],区间对应为[ left+sum[l-1], left+sum[r]-1 ]
56         return query(c + 1, l, mid, l + s, l + s + ss - 1, k);
57     }else{//sum[r]-sum[l-1]<k,查找rch[t],区间对应为[ mid+1+l-left-sum[l-1], mid+1+r-left-sum[r] ]
58         return query(c + 1, mid + 1, r, mid - l + 1 + ql - s, mid - l + 1 + qr - s - ss,k - ss);
59     }
60 }
61 int main(){
62     int i, j, k;
63     while(~scanf("%d%d", &n, &m)){
64         for (i = 1; i <= n; i++){
65             scanf("%d", &a[i]);
66             tree[0][i] = as[i] = a[i];
67         }
68         sort(as + 1as + 1 + n);
69         build(01, n);
70         while(m--){
71             scanf("%d%d%d",&i,&j,&k);// i,j分别为区间起始点,k为该区间第k大的数。
72             printf("%d\n", query(01, n, i, j, k));
73         }
74     }
75     return 0;

76 }

 

转载于:https://www.cnblogs.com/pony1993/archive/2012/07/17/2594544.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/361328.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Canvas事件绑定

canvas事件绑定 众所周知canvas是位图&#xff0c;在位图里我们可以在里面画各种东西&#xff0c;可以是图片&#xff0c;可以是线条等等。那我们想给canvas里的某一张图片添加一个点击事件该怎么做到。而js只能监听到canvas的事件&#xff0c;很明显这个图片是不存在与dom里面…

控件注册 - 利用资源文件将dll、ocx打包进exe文件(转)

很多时候自定义或者引用控件都需要注册才能使用&#xff0c;但是如何使要注册的dll或ocx打包到exe中&#xff0c;使用户下载以后看到的只是一个exe,点击直接运行呢&#xff1f;就像很多安全控件&#xff0c;如支付宝的aliedit.exe那样。 现在介绍一种使用资源文件&#xff0c;将…

Canvas-图片旋转

Canvas-图片旋转 众所周知canvas是位图&#xff0c;你可以在里面渲染你要的东西&#xff0c;不过你只能操作canvas的属性来进行编辑。就是说你并不能操作画进canvas的东西&#xff0c;例如我在canvas里添加一幅画&#xff0c;我现在想将那幅画移动10px&#xff0c;我们并不能直…

CSS3实现多页签图片缩放切换效果

多页签切换效果&#xff0c;图片缩放&#xff0c;鼠标移动到图片上后显示文字内容等等&#xff0c;效果很集中呐 截图如下&#xff1a; 下载地址&#xff1a;http://www.lanrenzhijia.com/js/css3/2012/0718/602.html 预览地址&#xff1a;http://www.lanrenzhijia.com/yulan/2…

Angular使用总结 --- 如何正确的操作DOM

无奈接手了一个旧项目&#xff0c;上一个老哥在Angular项目中大量使用了JQuery来操作DOM&#xff0c;真的是太不讲究了。那么如何优雅的使用Angular的方式来操作DOM呢&#xff1f; 获取元素 1、ElementRef --- A wrapper around a native element inside of a View. 在组件…

非首屏图片延时加载

目标 减少资源加载可以明显的优化页面加载的速度&#xff0c;所以可以减少页面载入时立即下载的图片的数量&#xff0c;以提高页面加载速度&#xff0c;其他的图片在需要的时候再进行加载。 思路 想要实现以上的目标&#xff0c;有几个地方需要思考。 1、如何判断哪些图片需要…

具有链接资源的Spring RestTemplate

Spring Data REST是一个了不起的项目&#xff0c;它提供了一些机制来将基于Spring Data的存储库中的资源公开为REST资源。 使用链接资源公开服务 考虑两个简单的基于JPA的实体&#xff0c;课程和教师&#xff1a; Entity Table(name "teachers") public class Tea…

用户会话,数据控件和AM池

最近&#xff0c;有人问我有关应用程序模块池的有趣问题。 众所周知&#xff0c;AM池包含用户会话引用的应用程序模块实例&#xff0c;这允许会话在后续请求时从池中获取完全相同的AM实例。 如果应用程序中有多个根应用程序模块&#xff0c;那么每个模块都将拥有自己的AM池&am…

用 CSS 实现元素垂直居中,有哪些好的方案?

DIV居中的经典方法 1. 实现DIV水平居中 设置DIV的宽高&#xff0c;使用margin设置边距0 auto&#xff0c;CSS自动算出左右边距&#xff0c;使得DIV居中。 1 div{ 2 width: 100px; 3 height: 100px; 4 margin: 0 auto; 5 } 缺点&#xff1a;需要设置div的宽度 2.…

使用wss和HTTPS / TLS保护WebSocket的安全

是这个博客的第50条提示&#xff0c;是的&#xff01; 技术提示&#xff03;49说明了如何使用用户名/密码和Servlet安全机制保护WebSocket的安全。 本技术提示将说明如何在WildFly上使用HTTPS / TLS保护WebSocket。 让我们开始吧&#xff01; 创建一个新的密钥库&#xff1a…

Java性能调优调查结果(第二部分)

这是系列文章的第二篇&#xff0c;我们将分析2014年10月进行的性能调整调查的结果。如果您尚未阅读第一部分&#xff0c;我们建议从此处开始 。 第二部分将重点监视Java应用程序的性能问题。 特别是&#xff0c;我们尝试回答以下问题&#xff1a; 人们如何发现性能问题&#x…

简单的css缩放动画,仿腾讯新闻的分享按钮和美团app底部的图标样式

最近看到一些好看的hover的图形缩放效果。然后自己就写了下&#xff0c;发现这2种效果都不错。如果伙伴们更好的实现方式可以在下面留言哦~ 还有美团的效果&#xff0c;我就不展示了&#xff0c;喜欢的可以去app应用上看看。 这两种效果&#xff0c;其实实现的原理是一样的&…

Java性能调优调查结果(第一部分)

我们在2014年10月进行了Java性能调优调查。该调查的主要目的是收集对Java性能世界的见解&#xff0c;以改进Plumbr产品。 但是&#xff0c;我们也很高兴与您分享有趣的结果。 我们收集的数据为进行冗长的分析提供了素材&#xff0c;因此我们决定将结果划分为一系列博客文章。 这…

asp.net ViewState详解

ViewState是一个被误解很深的动物了。我希望通过此文章来澄清人们对ViewState的一些错误认识。为了达到这个目的&#xff0c;我决定从头到尾详细的描述一下整个ViewState的工作机制&#xff0c;其中我会同时用一些例子说明我文章中的观点&#xff0c;结论。比如我会用静态控件(…

windows下命令行修改系统时间;修改系统时间的软件

找了很久,都没有找到,还找了关键词 dos下修改系统时间 因为看到linux下修改系统时间是用hwclock 命令写入主板芯片. 而我由于某些原因想自动化修改系统时间,所以找windows下修改系统时间的软件 没有找到. 有一个 意天禁止修改系统时间开发包(系统时间保护组件) 1.0.0.1 ,可以禁…

如何摆脱JavaFX中的重点突出显示

今天&#xff0c;有人问我是否知道摆脱JavaFX控件&#xff08;分别是按钮&#xff09;的焦点突出的方法&#xff1a; 有关此问题的大多数文章和提示建议添加&#xff1a; .button:focused {-fx-focus-color: transparent; }但是使用这种样式&#xff0c;仍然会留下这样的光芒…

Android工具HierarchyViewer 代码导读(3) -- 后台代码

在上文中&#xff0c;我们讲解了如何把HierarchyViewer的项目导入到Eclipse中&#xff0c;以便更高效阅读代码。本文将讲解HierarchyViewer的后台代码&#xff0c;建议大家可以先阅读<Android工具HierarchyViewer代码导读(1) -- 功能实现演示>一文, 其中的代码演示了Hier…

阿里巴巴使命、愿景、价值观、绩效管理中的六大价值观、

阿里巴巴的使命 让天下没有难做的生意 阿里巴巴的愿景 分享数据的第一平台幸福指数最高的企业“活102年”阿里巴巴的价值观 我们坚持“客户第一、员工第二、股东第三”。 阿里巴巴的六脉神剑&#xff08;绩效管理中的六大价值观&#xff09; 公司的“六脉神剑” 客户第一&#…

在命令行上操作JAR,WAR和EAR

尽管Java IDE和许多图形工具使查看和操作Java归档文件&#xff08;JAR&#xff0c;WAR和EAR&#xff09;文件的内容比以往更加容易&#xff0c;但有时我还是更喜欢使用命令行jar命令来完成这些任务。 当我必须重复做某事或作为脚本的一部分来做时&#xff0c;尤其如此。 在本文…

C#语言使用多态(接口与override) ——帮您剔除对面向对象多态性的疑惑

多态是面向对象编程中三大机制之一,其原理建立在"从父类继承而来的子类可以转换为其父类"这个规则之上,换句话说,能用父类的地方,就能用该类的子类.当从父类派生了很多子类时,由于每个子类都有其不同的代码实现,所以当用父类来引用这些子类时,同样的操作而可以表现出…