题意:二维平面上 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. 了解SVG

    页的节点类型,我们将说明怎样通过Illustrator高速的把SVG文档加入到网页中.我们还会讲讲D3.js,一个强大的.SVG控制的JavaScript库. "SVG并不仅仅用于像素处理. ...

  2. Cocos2dx 多线程

    多-threaded负荷plist特征.获取知识的必要性: 1.多线程开启:pthread 2.怎样在线程中载入plist 一.多线程开启 当我们想在程序中开多线程中.第一想到的是cocos2d-x有 ...

  3. linux下清理系统垃圾

    可以使用以下命令清理系统垃圾sudo apt-get autoclean 清理旧版本的软件缓存sudo apt-get clean 清理所有软件缓存sudo apt-get autoremove 删除 ...

  4. ulimit -n修改单进程可打开最大文件数目

    对所有用户都生效: vi /etc/profile 添加一行如下: ulimit -n 65535 执行source /etc/profile生效,不需要重启服务器. $ source /etc/pr ...

  5. sass笔记-2|Sass基础语法之让样式表更具条理性和可读性

    这一篇主要详述保持sass条理性和可读性的3个最基本方法--嵌套.导入和注释. 零. 变量 变量本身的作用是为了保持属性值的可维护性,把所有需要维护的属性值放在同一个地方,快速更改,处处生效,可谓售后 ...

  6. php 时间转换

    在数据库读出的数据,都是字符类型的,所以需要转换: 时间的转换:用date ()函数来实现时间格式; date() 函数默认时间是1970/01/01/ 00:00:00; 要想得到想要的时间就还得用 ...

  7. 【转】大素数判断和素因子分解【miller-rabin和Pollard_rho算法】

    集训队有人提到这个算法,就学习一下,如果用到可以直接贴模板,例题:POJ 1811 转自:http://www.cnblogs.com/kuangbin/archive/2012/08/19/2646 ...

  8. 反编译 APKTool 逆向助手

    最佳实践--Android逆向助手 1.点击"反编译apk,完成后res下的所有资源就都可以正常使用了,相当于apktool的功能------目前已失效,但是直接用rar解压是可以的!2.点 ...

  9. HDU3757

    题意:一些团队因为任务要去避难所,并且每个避难所必须要有团队在,避难所的数量小于等于团队的数量, 团队去避难所的消耗油量与路程成正比,求解最小耗油量.题目来源:2010 Northeastern Eu ...

  10. css书写步骤

    CSS整体书写步骤1:CSS RESET 重置2:CSS GLABAL 全局属性3: CSS分模块属性,(先写默认样式和设计图相差最大的部分,先大块布局,后细致调整) <style>/*C ...