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
原创粉丝点击