1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
| #include <algorithm> #include <cassert> #include <cctype> #include <cstdio> #include <cstring>
typedef long long ll;
template <typename T> inline T &read(T &x) { x = 0; bool f = false; short ch = getchar(); while (!isdigit(ch)) { if (ch == '-') f = true; ch = getchar(); } while (isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ '0'), ch = getchar(); if (f) x = -x; return x; }
const int N = 3e5 + 5, M = 1e6 + 5; int n, q, maxt, ans[N]; ll t;
struct Obj { int w, t; inline bool operator<(const Obj &rhs) const { return w < rhs.w; } } a[N];
struct SegmentTree { struct Node { int cnt; ll sum; } tr[M << 2];
inline void pushup(int x) { tr[x].sum = tr[x << 1].sum + tr[x << 1 | 1].sum; tr[x].cnt = tr[x << 1].cnt + tr[x << 1 | 1].cnt; }
ll query(int x, int l, int r, int p) { if (p == 0) return 0; if (l == r) { return (ll)p * l; } int mid = (l + r) >> 1; if (p <= tr[x << 1].cnt) return query(x << 1, l, mid, p); return tr[x << 1].sum + query(x << 1 | 1, mid + 1, r, p - tr[x << 1].cnt); }
void modify(int x, int l, int r, int p, int v) { if (l == r) { return tr[x].cnt += v, tr[x].sum += p * v, void(); } int mid = (l + r) >> 1; if (p <= mid) modify(x << 1, l, mid, p, v); else modify(x << 1 | 1, mid + 1, r, p, v); pushup(x); } } pre, suf;
int main() { #ifndef ONLINE_JUDGE #ifdef LOCAL freopen64("/tmp/CodeTmp/testdata.in", "r", stdin); freopen64("/tmp/CodeTmp/testdata.out", "w", stdout); #else freopen("treasure.in", "r", stdin); freopen("treasure.out", "w", stdout); #endif #endif
read(n), read(t), read(q); for (int i = 1; i <= n; ++i) read(a[i].w), maxt = std::max(maxt, read(a[i].t)); std::sort(a + 1, a + n + 1); for (int i = 1; i <= n; ++i) pre.modify(1, 0, maxt, a[i].t, 1); memset(ans, -1, sizeof(ans)); for (int i = n, j = 1; i && j <= n; --i) { pre.modify(1, 0, maxt, a[i].t, -1); while (((j >> 1) <= i - 1) && ((j >> 1) <= n - i) && (suf.query(1, 0, maxt, j >> 1) + pre.query(1, 0, maxt, j >> 1) + a[i].t <= t)) { ans[j] = a[i].w, j += 2; } suf.modify(1, 0, maxt, a[i].t, 1); } for (int i = 1, x; i <= q; ++i) { printf("%d\n", ans[read(x)]); } return 0; }
|