给出N个点(x,y)。每一个点有一个高度h

给出M次询问。问在(x,y)范围内第k小的高度是多少,没有输出-1 (k<=10)

线段树扫描线

首先离散化Y坐标,以Y坐标建立线段树

对全部的点和询问进行离线操作,将询问和点依照x,y的大小排序,从左向右,从下向上。对于同样的(x,y)插入点在询问点之前

线段树的每一个节点维护10个高度,每次询问[0,mark[i].y]的第mark[i].h高的值就可以

#include "stdio.h"
#include "string.h"
#include "algorithm"
#include "map"
using namespace std; map<int,int>mp;
struct Mark
{
int x,y,h,op,id;
}mark[60010];
struct Ans
{
int w; // 记录共同拥有多少个
int h[11];
}ans;
struct node
{
int l,r;
Ans x;
}data[300010];
int y[60010],pri[30010];
bool cmp_mark(Mark a,Mark b)
{
if (a.x!=b.x) return a.x<b.x;
else
if (a.y!=b.y) return a.y<b.y;
else
return a.op<b.op;
} Ans Merge(Ans a,Ans b)
{
int i,j,k;
Ans c;
i=j=k=1;
while ((i<=a.w || j<=b.w) && k<=10)
{
if (j > b.w || (i <= a.w && a.h[i] < b.h[j]) )
c.h[k++] = a.h[i++];
else
c.h[k++] = b.h[j++];
}
c.w=k-1;
return c;
} void build(int l,int r,int k)
{
int mid;
data[k].l=l;
data[k].r=r;
data[k].x.w=0; if(l==r) return ; mid=(l+r)/2; build(l,mid,k*2);
build(mid+1,r,k*2+1);
} void updata(int n,int op,int k)
{
int mid;
if (data[k].l==n && data[k].r==n)
{
data[k].x.w++;
data[k].x.h[data[k].x.w]=op;
sort(data[k].x.h+1,data[k].x.h+1+data[k].x.w);
return ;
} mid=(data[k].l+data[k].r)/2; if (n<=mid) updata(n,op,k*2);
else if (n>mid) updata(n,op,k*2+1); data[k].x=Merge(data[k*2].x,data[k*2+1].x);
} Ans query(int l,int r,int k)
{
int mid;
if (data[k].l==l && data[k].r==r)
return data[k].x; mid=(data[k].l+data[k].r)/2; if (r<=mid) return query(l,r,k*2);
else
if (l>mid) return query(l,r,k*2+1);
else
return Merge(query(l,mid,k*2),query(mid+1,r,k*2+1));
}
int main()
{
int n,m,i,cnt,temp;
while (scanf("%d%d",&n,&m)!=EOF)
{
for (i=0;i<n;i++)
{
scanf("%d%d%d",&mark[i].x,&mark[i].y,&mark[i].h);
y[i]=mark[i].y;
mark[i].op=1;
}
for (i=n;i<n+m;i++)
{
scanf("%d%d%d",&mark[i].x,&mark[i].y,&mark[i].h);
mark[i].id=i-n;
y[i]=mark[i].y;
mark[i].op=2;
}
cnt=n+m; sort(y,y+cnt);
sort(mark,mark+cnt,cmp_mark); temp=unique(y,y+cnt)-y; // 离散化 for (i=0;i<temp;i++)
mp[y[i]]=i; build(0,temp-1,1); for (i=0;i<cnt;i++)
{
if (mark[i].op==1)
updata(mp[mark[i].y],mark[i].h,1);
else
{
ans=query(0,mp[mark[i].y],1); // 询问返回该区间内前10个最小高度
if (mark[i].h<=ans.w)
pri[mark[i].id]=ans.h[mark[i].h];
else
pri[mark[i].id]=-1;
}
}
for (i=0;i<m;i++)
printf("%d\n",pri[i]);
}
return 0;
}

HDU 5107 线段树扫描线的更多相关文章

  1. hdu 4052 线段树扫描线、奇特处理

    Adding New Machine Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  2. hdu 1828 线段树扫描线(周长)

    Picture Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Sub ...

  3. hdu 5091(线段树+扫描线)

    上海邀请赛的一道题目,看比赛时很多队伍水过去了,当时还想了好久却没有发现这题有什么水题的性质,原来是道成题. 最近学习了下线段树扫描线才发现确实是挺水的一道题. hdu5091 #include &l ...

  4. hdu 1255(线段树 扫描线) 覆盖的面积

    http://acm.hdu.edu.cn/showproblem.php?pid=1255 典型线段树辅助扫描线,顾名思义扫描线就是相当于yy出一条直线从左到右(也可以从上到下)扫描过去,此时先将所 ...

  5. HDU 5091 线段树扫描线

    给出N个点.和一个w*h的矩形 给出N个点的坐标,求该矩形最多能够覆盖多少个点 对每一个点point(x.y)右边生成相应的点(x+w,y)值为-1: 纵向建立线段树,从左到右扫描线扫一遍.遇到点则用 ...

  6. hdu 1542 线段树+扫描线 学习

    学习扫描线ing... 玄学的东西... 扫描线其实就是用一条假想的线去扫描一堆矩形,借以求出他们的面积或周长(这一篇是面积,下一篇是周长) 扫描线求面积的主要思想就是对一个二维的矩形的某一维上建立一 ...

  7. hdu 4419 线段树 扫描线 离散化 矩形面积

    //离散化 + 扫描线 + 线段树 //这个线段树跟平常不太一样的地方在于记录了区间两个信息,len[i]表示颜色为i的被覆盖的长度为len[i], num[i]表示颜色i 『完全』覆盖了该区间几层. ...

  8. hdu 3265 线段树扫描线(拆分矩形)

    题意:        给你n个矩形,每个矩形上都有一个矩形的空洞,所有的矩形都是平行于x,y轴的,最后问所有矩形的覆盖面积是多少. 思路:       是典型的矩形覆盖问题,只不过每个矩形上多了一个矩 ...

  9. HDU 1828 线段树+扫描线(计算矩形周长并)

    题意:给你n个矩形,然后矩形有可能重叠,要你求周长 思路:首先碰到这种矩形在数轴上那么第一反应应该想到的是扫描线, 做周长我们有两种方法 第一种,我们可以分开两部分求,第一遍求x轴上的贡献,第二遍求y ...

随机推荐

  1. VS2008下直接安装使用Boost库1.46.1版本

    Boost库是一个可移植.提供源代码的C++库,作为标准库的后备,是C++标准化进程的发动机之一. Boost库由C++标准委员会库工作组成员发起,其中有些内容有望成为下一代C++标准库内容.在C++ ...

  2. addEventListener()及attachEvent()区别分析

    Javascript 的addEventListener()及attachEvent()区别分析 Mozilla中: addEventListener的使用方式: target.addEventLis ...

  3. MYSQL获取自增主键【4种方法】

    通常我们在应用中对mysql执行了insert操作后,需要获取插入记录的自增主键.本文将介绍java环境下的4种方法获取insert后的记录主键auto_increment的值: 通过JDBC2.0提 ...

  4. 微软vs2015先行,Visual Studio 2015正式版离线iso及在线下载(附key)附带百度云盘地址

    win10正式版发布之前我们迎来了vs2015正式版,迫不及待要下载朋友可以看看 Visual Studio Community 2015简体中文版(社区版,针对个人免费): 在线安装exe:http ...

  5. 【Demo 0006】Android 组件(Activity)

    本章学习要点:        1.  了解Activity基本概念;        2.  掌握Activity生命周期:        3.  掌握 Activity之间跳转:  

  6. [每日一题] OCP1z0-047 :2013-08-28 DELETE..........................................................160

    转载请注明出处:http://blog.csdn.net/guoyjoe/article/details/10475707 正确答案:ACD 根据题库,操作如下: A答案能删除: oe@OCM> ...

  7. 译文:前端性能的重要性 The Importance of Frontend Performance

    欢迎訪问我的主页.最新的文章我会首先公布在个人主页上: http://blog.guaidm.com/shocky/ 原书下载地址:http://pan.baidu.com/s/1pJocRwB 在我 ...

  8. 调用函数的ALV、面向对象的ALV设置带选择列

    这个就是通过对应的选择列,实现对ALV数据的选择,在调用函数的ALV和面向对象的ALV实现方法存在差异,下面讲两者的方法:1)调用函数的ALV.   通过 SLIS_LAYOUT_ALV-BOX_FI ...

  9. webdynpro 调用应用程序做跳转

    1.是调用指的是调用生成应用程序,非webdynpro组件程序, 如下: 1)调用页面,并传值 METHOD get_zgmtpage . DATA:lw_application_name TYPE ...

  10. 【ASP.NET Web API教程】5.3 发送HTML表单数据:文件上传与多部分MIME

    原文:[ASP.NET Web API教程]5.3 发送HTML表单数据:文件上传与多部分MIME 注:本文是[ASP.NET Web API系列教程]的一部分,如果您是第一次看本系列教程,请先看前面 ...