Submission #1309747

#TimeUsernameProblemLanguageResultExecution timeMemory
1309747kawhietExamination (JOI19_examination)C++20
100 / 100
307 ms50256 KiB
#include <bits/stdc++.h>
using namespace std;

struct MergeSortTree {
    int n;
    vector<int> a;
    vector<vector<int>> t;

    MergeSortTree(vector<int> k) {
        n = k.size();
        a = k;
        t.resize(4 * n);
        build(0, 0, n - 1);
    }

    vector<int> merge(vector<int> x, vector<int> y) {
        vector<int> s;
        int n = x.size(), m = y.size();
        int i = 0, j = 0;
        while (i < n && j < m) {
            if (x[i] < y[j]) {
                s.push_back(x[i++]);
            } else {
                s.push_back(y[j++]);
            }
        }
        for (; i < n; i++) s.push_back(x[i]);
        for (; j < m; j++) s.push_back(y[j]);
        return s;
    }

    void build(int id, int tl, int tr) {
        if (tl == tr) {
            t[id] = {a[tl]};
            return;
        }
        int x = 2 * id + 1, y = x + 1, tm = (tl + tr) / 2;
        build(x, tl, tm);
        build(y, tm + 1, tr);
        t[id] = merge(t[x], t[y]);
    }

    int get(int id, int tl, int tr, int l, int r, int u) {
        if (r < tl || tr < l) return 0;
        if (l <= tl && tr <= r) {
            return ranges::lower_bound(t[id], u) - t[id].begin();
        }
        int x = 2 * id + 1, y = x + 1, tm = (tl + tr) / 2;
        return get(x, tl, tm, l, r, u) + get(y, tm + 1, tr, l, r, u);
    }

    int get(int l, int r, int u) { return get(0, 0, n - 1, l, r, u); }
};

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n, q;
    cin >> n >> q;
    vector<int> s(n), t(n);
    for (int i = 0; i < n; i++) {
        cin >> s[i] >> t[i];
    }
    vector<int> ord(n);
    iota(ord.begin(), ord.end(), 0);
    ranges::sort(ord, [&](int i, int j) {
        return s[i] + t[i] < s[j] + t[j];
    });
    vector<int> a(n), b(n), k(n);
    for (int i = 0; i < n; i++) {
        a[i] = s[ord[i]];
        b[i] = t[ord[i]];
        k[i] = a[i] + b[i];
    }
    MergeSortTree t_a(a), t_b(b);
    while (q--) {
        int x, y, z;
        cin >> x >> y >> z;
        z = max(z, x + y);
        int pos = ranges::lower_bound(k, z) - k.begin();
        if (pos == n) {
            cout << 0 << '\n';
            continue;
        }
        int ans = n - pos;
        ans -= t_a.get(pos, n - 1, x);
        ans -= t_b.get(pos, n - 1, y);
        cout << ans << '\n';
    }
    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...