题意:二维平面上 N 个高度为 Hi 建筑物,M次询问,每次询问输出 位于坐标(x ,y)左下角(也就是xi <= x && yi <= y)的建筑物中的第k高的建筑物的高度,如果不存在输出-1.

思路:可以发现k很小,最大才是10。对于区间第k大的问题,如果k很小的话,线段树也是可以的,,当然这里要用到 区间合并,对于每个节点 记录其 孩子中 前2*k个高度(不一定非要2*k,只要大于k就可以,至于为什么,自己可以想想),进行合并排序。

 #include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std; const int maxn = 3e4+;
struct Building
{
int x,y,flag,k,idx;
Building (){}
Building (int _x,int _y,int _z): x(_x),y(_y),k(_z){}
bool operator < (const Building &rhs)const
{
return x < rhs.x || (x == rhs.x && y < rhs.y) ||
(x == rhs.x && y == rhs.y && flag < rhs.flag);
}
}bui[maxn<<];
struct Seg_tree
{
int sum,num[];
Seg_tree (){sum = ;}
}seg[maxn<<]; //正常来说4倍就够了,可是这题不是maxn而是2*maxn,所以要(2*maxn)*4倍
int vec[maxn*],ans[maxn*];
void build (int l,int r,int pos)
{
seg[pos].sum = ;
if (l == r)
return;
int mid = (l + r) >> ;
build(l,mid,pos<<);
build(mid+,r,pos<<|);
}
void _sort(int pos)
{
sort(seg[pos].num,seg[pos].num+seg[pos].sum);
seg[pos].sum = min(,seg[pos].sum);
}
void push_up(int pos)
{
int tot = ;
for (int i = ; i < seg[pos<<].sum; i++)
seg[pos].num[tot++] = seg[pos<<].num[i];
for (int i = ; i < seg[pos<<|].sum; i++)
seg[pos].num[tot++] = seg[pos<<|].num[i];
seg[pos].sum = tot;
_sort(pos);
}
void update(int l,int r,int pos,int p,int val)
{
if (l == r)
{
seg[pos].num[seg[pos].sum++] = val;
_sort(pos); //对当前节点内的高度进行排序
return;
}
int mid = (l + r) >> ;
if (p <= mid)
update(l,mid,pos<<,p,val);
else
update(mid+,r,pos<<|,p,val);
push_up(pos); //左右孩子合并 取出前10个高度
}
int pre_ans[],siz;
void query(int l,int r,int pos,int ua,int ub)
{
if (ua <= l && ub >= r)
{
for (int i = ; i < seg[pos].sum; i++)
pre_ans[siz++] = seg[pos].num[i];
sort(pre_ans,pre_ans+siz);
siz = min(,siz);
return;
}
int mid = (l + r) >> ;
if (ua <= mid)
query (l,mid,pos<<,ua,ub);
if (ub > mid)
query (mid+,r,pos<<|,ua,ub);
}
int main(void)
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
int n,m;
while (~scanf ("%d%d",&n,&m))
{
int tot = ;
for (int i = ; i < n + m ; i++)
{
int u,v,c;
scanf ("%d%d%d",&u,&v,&c);
bui[i] = Building (u,v,c);
if (i < n)
bui[i].flag = ;
else
bui[i].flag = ;
vec[tot++] = v;
bui[i].idx = i;
}
sort(vec,vec+tot);
sort(bui,bui+n+m);
tot = unique(vec, vec + tot) - vec;
build(,tot,);
for (int i = ; i < n + m; i++)
{
int p = + lower_bound(vec,vec+tot,bui[i].y) - vec;
if (bui[i].flag == )
update(,tot,,p,bui[i].k);
else
{
siz = ;
query(,tot,,,p);
if (bui[i].k > siz)
ans[bui[i].idx] = -;
else
ans[bui[i].idx] = pre_ans[bui[i].k-];
}
}
for (int i = n; i < n + m; i++)
printf("%d\n",ans[i]);
}
return ;
}

HDU5107---K-short Problem (线段树区间 合并、第k大)的更多相关文章

  1. poj-3667(线段树区间合并)

    题目链接:传送门 参考文章:传送门 思路:线段树区间合并问题,每次查询到满足线段树的区间最左值,然后更新线段树. #include<iostream> #include<cstdio ...

  2. hdu-3308 LCIS (线段树区间合并)

    LCIS Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  3. hdu 3308(线段树区间合并)

    LCIS Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  4. poj3667 线段树 区间合并

    //Accepted 3728 KB 1079 ms //线段树 区间合并 #include <cstdio> #include <cstring> #include < ...

  5. hdu3911 线段树 区间合并

    //Accepted 3911 750MS 9872K //线段树 区间合并 #include <cstdio> #include <cstring> #include < ...

  6. 【bzoj2325】[ZJOI2011]道馆之战 树链剖分+线段树区间合并

    题目描述 给定一棵树,每个节点有上下两个格子,每个格子的状态为能走或不能走.m次操作,每次修改一个节点的状态,或询问:把一条路径上的所有格子拼起来形成一个宽度为2的长方形,从起点端两个格子的任意一个开 ...

  7. 【BZOJ3638】Cf172 k-Maximum Subsequence Sum 线段树区间合并(模拟费用流)

    [BZOJ3638]Cf172 k-Maximum Subsequence Sum Description 给一列数,要求支持操作: 1.修改某个数的值 2.读入l,r,k,询问在[l,r]内选不相交 ...

  8. 【bzoj3638】Cf172 k-Maximum Subsequence Sum 模拟费用流+线段树区间合并

    题目描述 给一列数,要求支持操作: 1.修改某个数的值 2.读入l,r,k,询问在[l,r]内选不相交的不超过k个子段,最大的和是多少. 输入 The first line contains inte ...

  9. HDU 3308 (线段树区间合并)

    http://acm.hdu.edu.cn/showproblem.php?pid=3308 题意: 两个操作  : 1 修改 单点  a 处的值. 2 求出 区间[a,b]内的最长上升子序列. 做法 ...

  10. LCIS HDU - 3308 (线段树区间合并)

    LCIS HDU - 3308 Given n integers. You have two operations: U A B: replace the Ath number by B. (inde ...

随机推荐

  1. Node.js初体验

    1.Node.js是什么 [1]Node是一个server端 JavaScript 解释器,但是真的以为JavaScript不错的同学学习Node就能轻松拿下,那么你就错了.总结:水深不深我还不知道, ...

  2. 【iOS】Resumable Doanloads(断点下载)

    这里我们只讨论iOS平台下的通用app,我们可以自己写代码来实现resume downloads,解释如下. resume一个HTTP下载不难,但必须要理解一些关键的HTTP概念: entity ta ...

  3. ls Common Command-Line Options

    ls  Common Command-Line Options Command  Use: ls -l    Shows a long listing, which includes informat ...

  4. maven部署命令

    参考文档:http://blog.csdn.net/woshixuye/article/details/8133050 http://www.blogjava.net/itvincent/archiv ...

  5. asp.mvc获取checkbox、radio、select的值

    记录一下在asp.mvc中,提交表单时后台获取checkbox.radio.select值的方法. 1.获取select的值 <select name="type"> ...

  6. Linq使用GroupBy筛选数据

    StringBuilder sb = new StringBuilder(); List<IGrouping<string, modle>> listRepeat = mode ...

  7. 【sql】经典SQL语句大全

    原文链接:http://www.cnblogs.com/yubinfeng/archive/2010/11/02/1867386.html —————————————————————————————— ...

  8. 如何删除Windows服务

    删除的办法有两个: 办法一: 用sc.exe这个Windows命令         开始——运行——cmd.exe,然后输入sc就可以看到了.使用办法很简单:         sc delete &q ...

  9. vim 学习笔记

    vim介绍:一款编辑器,另外一般linux系统会自带,所以一般linux下日志.配置文件等 纯文本文件的修改编辑等通过vim操作 学会的好处:1 方便操作linux下日志.配置文件等纯文本文件 2 功 ...

  10. iOS9之后对于NSURL的编码转换方法变化说明

    在iOS9之后,官方推荐使用下面的方法对NSString进行转换 - (nullable NSString *)stringByAddingPercentEncodingWithAllowedChar ...