HDU5107---K-short Problem (线段树区间 合并、第k大)
题意:二维平面上 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大)的更多相关文章
- poj-3667(线段树区间合并)
题目链接:传送门 参考文章:传送门 思路:线段树区间合并问题,每次查询到满足线段树的区间最左值,然后更新线段树. #include<iostream> #include<cstdio ...
- hdu-3308 LCIS (线段树区间合并)
LCIS Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- hdu 3308(线段树区间合并)
LCIS Time Limit: 6000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submis ...
- poj3667 线段树 区间合并
//Accepted 3728 KB 1079 ms //线段树 区间合并 #include <cstdio> #include <cstring> #include < ...
- hdu3911 线段树 区间合并
//Accepted 3911 750MS 9872K //线段树 区间合并 #include <cstdio> #include <cstring> #include < ...
- 【bzoj2325】[ZJOI2011]道馆之战 树链剖分+线段树区间合并
题目描述 给定一棵树,每个节点有上下两个格子,每个格子的状态为能走或不能走.m次操作,每次修改一个节点的状态,或询问:把一条路径上的所有格子拼起来形成一个宽度为2的长方形,从起点端两个格子的任意一个开 ...
- 【BZOJ3638】Cf172 k-Maximum Subsequence Sum 线段树区间合并(模拟费用流)
[BZOJ3638]Cf172 k-Maximum Subsequence Sum Description 给一列数,要求支持操作: 1.修改某个数的值 2.读入l,r,k,询问在[l,r]内选不相交 ...
- 【bzoj3638】Cf172 k-Maximum Subsequence Sum 模拟费用流+线段树区间合并
题目描述 给一列数,要求支持操作: 1.修改某个数的值 2.读入l,r,k,询问在[l,r]内选不相交的不超过k个子段,最大的和是多少. 输入 The first line contains inte ...
- HDU 3308 (线段树区间合并)
http://acm.hdu.edu.cn/showproblem.php?pid=3308 题意: 两个操作 : 1 修改 单点 a 处的值. 2 求出 区间[a,b]内的最长上升子序列. 做法 ...
- LCIS HDU - 3308 (线段树区间合并)
LCIS HDU - 3308 Given n integers. You have two operations: U A B: replace the Ath number by B. (inde ...
随机推荐
- Node.js初体验
1.Node.js是什么 [1]Node是一个server端 JavaScript 解释器,但是真的以为JavaScript不错的同学学习Node就能轻松拿下,那么你就错了.总结:水深不深我还不知道, ...
- 【iOS】Resumable Doanloads(断点下载)
这里我们只讨论iOS平台下的通用app,我们可以自己写代码来实现resume downloads,解释如下. resume一个HTTP下载不难,但必须要理解一些关键的HTTP概念: entity ta ...
- ls Common Command-Line Options
ls Common Command-Line Options Command Use: ls -l Shows a long listing, which includes informat ...
- maven部署命令
参考文档:http://blog.csdn.net/woshixuye/article/details/8133050 http://www.blogjava.net/itvincent/archiv ...
- asp.mvc获取checkbox、radio、select的值
记录一下在asp.mvc中,提交表单时后台获取checkbox.radio.select值的方法. 1.获取select的值 <select name="type"> ...
- Linq使用GroupBy筛选数据
StringBuilder sb = new StringBuilder(); List<IGrouping<string, modle>> listRepeat = mode ...
- 【sql】经典SQL语句大全
原文链接:http://www.cnblogs.com/yubinfeng/archive/2010/11/02/1867386.html —————————————————————————————— ...
- 如何删除Windows服务
删除的办法有两个: 办法一: 用sc.exe这个Windows命令 开始——运行——cmd.exe,然后输入sc就可以看到了.使用办法很简单: sc delete &q ...
- vim 学习笔记
vim介绍:一款编辑器,另外一般linux系统会自带,所以一般linux下日志.配置文件等 纯文本文件的修改编辑等通过vim操作 学会的好处:1 方便操作linux下日志.配置文件等纯文本文件 2 功 ...
- iOS9之后对于NSURL的编码转换方法变化说明
在iOS9之后,官方推荐使用下面的方法对NSString进行转换 - (nullable NSString *)stringByAddingPercentEncodingWithAllowedChar ...