hdu 5107 K-short Problem(线段树)
来源:互联网 发布:笔趣阁 知乎 编辑:程序博客网 时间:2024/06/11 13:47
题目链接:hdu 5107 K-short Problem
题目大意:有N个点,M次询问,每次询问点X,Y,K,表示在点集合{(x,y)|x≤X,y≤Y}中高度第K小的值是多少,没有的
话输出-1。
解题思路:线段树,每个节点维护10个高度(因为K最大为10),将询问和点按照x,y的大小排序,从左向右,从下向
上,每次询问就查询[0,idx(y)]即可。注意如果询问和点的位置相同,要先插入点。
#include <cstdio>#include <cstring>#include <vector>#include <algorithm>using namespace std;const int maxn = 60005;struct node { int n, high[15]; node() { n = 0; } void insert(int h) { if (n < 10) high[n++] = h; else if (h < high[n-1]) high[n-1] = h; sort(high, high + n); }};#define lson(x) ((x)<<1)#define rson(x) (((x)<<1)|1)int lc[maxn << 2], rc[maxn << 2];node nd[maxn << 2];inline node merge (node a, node b) { node ret; int p = 0, q = 0; while ((p < a.n || q < b.n) && ret.n <= 10) { if (q >= b.n || (p < a.n && a.high[p] < b.high[q]) ) ret.high[ret.n++] = a.high[p++]; else ret.high[ret.n++] = b.high[q++]; } return ret;}void build(int u, int l, int r) { lc[u] = l; rc[u] = r; if (l == r) { nd[u].n = 0; return ; } int mid = (l + r) >> 1; build(lson(u), l, mid); build(rson(u), mid + 1, r); nd[u] = merge(nd[lson(u)], nd[rson(u)]);}void insert (int u, int x, int h) { if (x == lc[u] && rc[u] == x) { nd[u].insert(h); return; } int mid = (lc[u] + rc[u]) >> 1; if (x <= mid) insert(lson(u), x, h); else insert(rson(u), x, h); nd[u] = merge(nd[lson(u)], nd[rson(u)]);}node query(int u, int l, int r) { if (l <= lc[u] && rc[u] <= r) return nd[u]; node ret; int mid = (lc[u] + rc[u]) >> 1; if (l <= mid) ret = merge(ret, query(lson(u), l, r)); if (r > mid) ret = merge(ret, query(rson(u), l, r)); return ret;}struct state { int x, y, h, id;}cmd[maxn + 5];vector<int> pos, tmp;int N, M, T, ans[30005];void init () { T = N + M; pos.clear(); tmp.clear(); int x, y, h; for (int i = 0; i < N; i++) { scanf("%d%d%d", &x, &y, &h); tmp.push_back(y); cmd[i] = (state) {x, y, h, 0}; } for (int i = 0; i < M; i++) { scanf("%d%d%d", &x, &y, &h); tmp.push_back(y); cmd[i+N] = (state) {x, y, h, i+1}; } sort(tmp.begin(), tmp.end()); pos.push_back(tmp[0]); for (int i = 1; i < tmp.size(); i++) { if (tmp[i] != tmp[i-1]) pos.push_back(tmp[i]); } build(1, 0, pos.size()-1);}inline int find(int x) { return lower_bound(pos.begin(), pos.end(), x) - pos.begin();}inline bool cmp (const state& a, const state& b) { if (a.x != b.x) return a.x < b.x; if (a.y != b.y) return a.y < b.y; return a.id < b.id;}void solve () { sort(cmd, cmd + T, cmp); for (int i = 0; i < T; i++) { if (cmd[i].id) { node tmp = query(1, 0, find(cmd[i].y)); int kth = cmd[i].h; ans[cmd[i].id] = (tmp.n >= kth ? tmp.high[kth-1] : -1); } else insert(1, find(cmd[i].y), cmd[i].h); }}int main () { while (scanf("%d%d", &N, &M) == 2) { init(); solve(); for (int i = 1; i <= M; i++) printf("%d\n", ans[i]); } return 0;}
0 0
- hdu 5107 K-short Problem(线段树)
- 【HDU】5107 K-short Problem 线段树
- hdu 5107 K-short Problem 线段树扫描线
- HDU 5107 K-short Problem(线段树,离线)
- BestCoder Round #18 1004 &&hdu 5107 K-short Problem 线段树
- hdu5107 K-short Problem(线段树+离散化+思维)
- hdu5107 K-short Problem 离线,离散化,线段树
- hdu 4291A Short problem
- hdu 4291 A Short problem
- hdu 4291 A Short problem
- HDU 4291 A Short problem
- hdu 4291 A Short problem 矩阵+循环
- hdu 5475 An easy problem(线段树)
- hdu 5475 An easy problem 线段树
- HDU 5443The Water Problem 线段树
- hdu 5475 An easy problem (线段树)
- 【线段树】HDU 5443 The Water Problem
- HDU-5475-An easy problem【线段树】
- jQuery表格插件(隔行换色、划过变色、全选)
- 【初学】android笔记
- 如何实时查看linux下的日志
- 位运算之美--用 +、- 和位运算实现正整数除法和取模(2)
- 插入排序,选择排序,递归排序和冒泡排序的实现
- hdu 5107 K-short Problem(线段树)
- [C++]LeetCode: 17 Reverse Integer
- Spring-AMQP连接和资源管理
- 《数据结构》第三章 栈和队列 知识结构导图——信管1133-09
- Java 单例模式
- ASP.NET网站管理系统退出 清除浏览器缓存,Session的代码
- jquery-easyui学习(2)_easyloader
- MFC控件的绘制与响应顺序——ZOrder
- 我是如何自学编程的——“3遍读书法”