K-short Problem

K-short Problem

Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 693    Accepted Submission(s): 217


Problem Description
In the view of a satellite, you can see lots of tall buildings in the city, and we assume that the city's border is flat. Now you have observed n tall buildings in the city and recorded their position and height. Due to some mysterious reasons, you need to answer a series of queries. Each query will give you a position(x, y) and k, then you have to find out the k-th shortest building in set{ (x,y)|xX,yY}.
 
Input
Multiple test cases.For each test case, the first line will contain two integers n and m( 0<n30000,0m30000), which represents the amount of buildings and amount of queries. Then n lines follow, contains three integers x,y,h(1E9x,y1E9,0h1E9) indicate the building's position and height in each line. Then there are m lines, each with three integers x,y,k(1E9x,y1E9,1k10) used for query.
 
Output
For each test case, if the k-th shortest building exists, output its height in 1 line, otherwise print "-1" (without quotes).
 
Sample Input
5 2 1 1 1 2 2 2 3 3 3 4 4 4 5 5 5 0 0 1 6 3 2
 
Sample Output
-1 2
 
#include <bits/stdc++.h>

typedef long long ll;
using namespace std;
const int maxn = 6e4 + 10;

struct answer {
    int tot;
    int rk[16];

    answer() {
        tot = 0;
    }

    inline void insert(int val) {
        if (tot <= 10) {
            rk[++tot] = val;
        } else if (val < rk[tot]) {
            rk[tot] = val;
        }
        sort(rk + 1, rk + 1 + tot);
    }
} ans[maxn<<2];

struct atom {
    int x, y, height, id;

    bool operator<(const atom &cur) const {
        if (x != cur.x)return x < cur.x;
        if (y != cur.y)return y < cur.y;
        return id < cur.id;
    }
} o[maxn<<1];

int n, m, cnt;
int ls[maxn<<2], rs[maxn<<2];

vector<int> re, lsh;

inline answer merge(answer s, answer t) {
    answer cur;
    int ss = 1, tt = 1;
    while ((ss <= s.tot || tt <= t.tot) && cur.tot <= 10) {
        if (tt > t.tot || (ss <= s.tot && s.rk[ss] < t.rk[tt])) {
            cur.rk[++cur.tot] = s.rk[ss++];
        } else {
            cur.rk[++cur.tot] = t.rk[tt++];
        }
    }
    return cur;
}

inline void build(int rt, int l, int r) {
    ls[rt] = l;
    rs[rt] = r;
    if (l == r) {
        ans[rt].tot = 0;
        return;
    }
    int mid = l + r >> 1;
    build(rt << 1, l, mid);
    build(rt << 1 | 1, mid + 1, r);
    ans[rt] = merge(ans[rt << 1], ans[rt << 1 | 1]);
}

inline void insert(int rt, int pos, int val) {
    if (ls[rt] == pos && rs[rt] == pos) {
        ans[rt].insert(val);
        return;
    }
    int mid = ls[rt] + rs[rt] >> 1;
    if (pos <= mid) {
        insert(rt << 1, pos, val);
    } else {
        insert(rt << 1 | 1, pos, val);
    }
    ans[rt] = merge(ans[rt << 1], ans[rt << 1 | 1]);
}

inline void init() {
    re.clear();
    lsh.clear();
    int x, y, height;
    for (register int i = 1; i <= n; ++i) {
        scanf("%d%d%d", &x, &y, &height);
//        x=rand()%100;
//        y=rand()%100;
//        height=rand()%8;
        re.emplace_back(y);
        o[i] = (atom) {x, y, height, 0};
    }
    for (register int i = 1; i <= m; ++i) {
        scanf("%d%d%d", &x, &y, &height);
//        x=rand()%100;
//        y=rand()%100;
//        height=rand()%8;
        re.emplace_back(y);
        o[i + n] = (atom) {x, y, height, i};
    }
    sort(re.begin(), re.end());
    lsh.emplace_back(re[0]);
    for (register int i = 1; i < re.size(); ++i) {
        if (re[i] != re[i - 1]) {
            lsh.emplace_back(re[i]);
        }
    }
//    for (register int i = 0; i < re.size(); ++i) {
//        printf("%d ", re[i]);
//    }
//    printf("\n");
    build(1, 0, lsh.size()-1);
}

inline answer query(int rt, int l, int r) {
    if (l <= ls[rt] && r >= rs[rt]) {
        return ans[rt];
    }
    int mid = (ls[rt] + rs[rt]) >> 1;
    answer cur;
    if (l <= mid) {
        cur = merge(cur, query(rt << 1, l, r));
    }
    if (r > mid) {
        cur = merge(cur, query(rt << 1 | 1, l, r));
    }
    return cur;
}

int e[maxn];

inline int getid(int se) {
    return lower_bound(lsh.begin(), lsh.end(), se) - lsh.begin();
}

inline void solve() {
    sort(o + 1, o + 1 + n + m);
    for (register int i = 1; i <= n + m; ++i) {
        if (o[i].id) {
            answer res = query(1, 0, getid(o[i].y));
            int K_th = o[i].height;
            if (K_th > res.tot) {
                e[o[i].id] = -1;
            } else {
                e[o[i].id] = res.rk[K_th];
            }
        } else {
            insert(1, getid(o[i].y), o[i].height);
        }
    }
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("1.txt", "r", stdin);
#endif
    while (scanf("%d%d", &n, &m) == 2) {
        init();
        solve();
        for (register int i = 1; i <= m; ++i) {
            printf("%d\n", e[i]);
        }
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/czy-power/p/11449281.html