제출 #1328640

#제출 시각아이디문제언어결과실행 시간메모리
1328640AzeTurk810Examination (JOI19_examination)C++20
100 / 100
536 ms53532 KiB
/*
Telebe of Adicto && Mamedov yani AzeTurk810
I see humans but no humanity
*/
#include <algorithm>
#include <array>
#include <iostream>
#include <map>
#include <utility>
#include <vector>

// mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

using ll = long long;
using namespace std;

#define ln '\n'
#define INFi 1e9
#define INFll 1e18

#ifdef ONPC
#include <algo.hpp>
#else
#define dbg(...)
#define dbg_out(...)
#endif

map<int, int> mp;
int compress(vector<int> A) {
    sort(A.begin(), A.end());
    int nxt = 1;
    mp[A[0]] = nxt;
    for (int i = 1; i < A.size(); i++) {
        if (A[i] != A[i - 1])
            nxt++;
        mp[A[i]] = nxt;
    }
    return nxt;
}

struct segmentTree {
    int N, Null_val;
    vector<int> t;

    segmentTree(int _n) {
        t.resize(_n * 4);
        N = _n;
        Null_val = 0;
    }

    void build(int v, int l, int r, vector<int> &a) {
        if (l == r) {
            t[v] = a[l];
            return;
        }
        int mid = (l + r) >> 1;
        build((v << 1), l, mid, a);
        build((v << 1) | 1, mid + 1, r, a);
        t[v] = t[(v << 1)] + t[(v << 1) | 1];
    }

    void upd(int v, int l, int r, int val, int &pos) {
        if (l == r) {
            t[v] += val;
            return;
        }
        int mid = (l + r) >> 1;
        if (mid >= pos)
            upd((v << 1), l, mid, val, pos);
        else
            upd((v << 1) | 1, mid + 1, r, val, pos);
        t[v] = t[(v << 1)] + t[(v << 1) | 1];
    }

    int ask(int v, int l, int r, int ql, int qr) {
        if (ql <= l && r <= qr)
            return t[v];
        if (ql > r || l > qr)
            return Null_val;
        int mid = (l + r) >> 1;
        return (ask((v << 1), l, mid, ql, qr) +
                ask((v << 1) | 1, mid + 1, r, ql, qr));
    }
};

char solve() {
    int N, Q;
    if (!(cin >> N >> Q))
        return 1;
    vector<array<int, 4>> st(N + 1);
    vector<int> nums;
    nums.push_back(0);
    for (int i = 0; i < N; i++) {
        cin >> st[i][0] >> st[i][1];
        st[i][2] = st[i][0] + st[i][1];
        nums.push_back(st[i][0]);
        nums.push_back(st[i][1]);
        nums.push_back(st[i][2]);
        st[i][3] = i;
    }
    vector<array<int, 4>> query, query2;
    for (int i = 0; i < Q; i++) {
        int X, Y, Z;
        cin >> X >> Y >> Z;
        nums.push_back(X);
        nums.push_back(Y);
        nums.push_back(Z);
        if (X + Y >= Z)
            query.push_back({X, Y, Z, i});
        else
            query2.push_back({X, Y, Z, i});
    }
    vector<int> ans(N);
    int M = compress(nums);
    for (int i = 0; i < N; i++) {
        st[i][0] = mp[st[i][0]];
        st[i][1] = mp[st[i][1]];
        st[i][2] = mp[st[i][2]];
    }
    for (auto &[l, r, z, id] : query) {
        l = mp[l];
        r = mp[r];
        z = mp[z];
    }
    for (auto &[l, r, z, id] : query2) {
        l = mp[l];
        r = mp[r];
        z = mp[z];
    }
    dbg(st);
    dbg(query);
    dbg(query2);
    sort(st.begin(), st.end(), [&](auto l, auto r) {
        if (l[0] == r[0])
            return l[1] > r[1];
        return l[0] > r[0];
    });

    sort(query.begin(), query.end(), [&](auto l, auto r) {
        if (l[0] == r[0])
            return l[1] > r[1];
        return l[0] > r[0];
    });
    sort(query2.begin(), query2.end(), [&](auto l, auto r) {
        if (l[2] != r[2])
            return l[2] > r[2];
        if (l[0] == r[0])
            return l[1] > r[1];
        return l[0] > r[0];
    });
    { // NOTE: A + B >= Z
        segmentTree t(M + 1);
        for (int i = 0, j = 0; i < query.size(); i++) {
            // cerr << j << ' ' << st.size() << ' ' << st[j][0] << '|' << query[i][0] << endl;
            while (j < st.size() && st[j][0] >= query[i][0]) {
                t.upd(1, 1, M, 1, st[j][1]);
                j++;
            }
            // cerr << i << ' ' << j << ' ' << query[i][3] << ' ' << t.ask(1, 1, M, query[i][1], M) << ln;
            ans[query[i][3]] = t.ask(1, 1, M, query[i][1], M);
        }
    }
    { // NOTE: build for next wave
        sort(st.begin(), st.end(), [&](auto l, auto r) {
            if (l[2] != r[2])
                return l[2] > r[2];
            if (l[0] == r[0])
                return l[1] > r[1];
            return l[0] > r[0];
        });
    }
    { // NOTE: A + B < Z
        segmentTree l(M + 1), r(M + 1);
        for (int i = 0, j = 0; i < query2.size(); i++) {
            while (j < st.size() && st[j][2] >= query2[i][2]) {
                l.upd(1, 1, M, 1, st[j][0]);
                r.upd(1, 1, M, 1, st[j][1]);
                j++;
            }
            int cur = l.ask(1, 1, M, 1, query2[i][0] - 1);
            cur += r.ask(1, 1, M, 1, query2[i][1] - 1);
            ans[query2[i][3]] = j - cur;
        }
    }
    for (int i = 0; i < Q; i++) {
        cout << ans[i] << ln;
    }
    cout << ln;
    return 0;
}

// Attack on titan<3

signed main() {
    ios::sync_with_stdio(0);
    cin.tie(nullptr);
    int t = 1e9;
    // cin >> t;
    for (int cases = 0; cases < t; cases++) {
        if (solve())
            break;
#ifdef ONPC
        cerr << "__________\n";
#endif
    }
}
// Just Imaginary
/*
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⣀⠀⠀⠀⢀⣴⣾⠀⠀⠀⡀⢀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⣦⣾⣿⣿⣿⣿⣿⡆⠁⠀⢀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠹⣿⣿⣿⣿⣿⣿⣿⣿⡿⠁⠀⡠⠂⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣀⠠⠔⠚⣿⣿⣿⣿⣿⣦⡄⠀⠁⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⢀⠠⠐⢂⠉⡀⣀⣤⣄⢻⣿⣿⡟⢈⡹⣿⡀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⡀⠄⠂⠈⠀⣶⣤⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠘⣷⡀⠀⡀⠐⠂⠐⢄
⠀⠀⠀⠀⠀⠀⠀⣿⣿⠟⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧⣀⣾⣷⠯⠀⠤⠤⠄⠈
⠀⠀⠀⠀⠀⠀⣼⣿⡟⠀⠀⣹⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣄⡀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⣰⣿⠋⠀⠀⢠⣾⣿⣿⣿⣿⣿⣭⠟⢻⣿⣿⣿⣿⡿⠁⠀⠀⠀⠀
⠀⠀⠀⣀⣶⡟⠁⠀⢾⣶⣿⠟⠉⠈⢻⣿⣿⣿⣦⣜⠀⠛⠛⠿⠁⠀⠀⠀⠀⠀
⠚⠻⠿⠿⡿⠁⠀⢠⣿⣿⠁⠀⣠⠖⠋⠉⠻⣿⣿⣿⣶⡀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⠀⠀⣰⣿⡿⠃⠠⠊⠁⠀⠀⠀⠀⠈⢿⣿⣿⠟⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⠀⢀⣴⡿⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀
⠀⠀⠀⣠⣾⠏⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
⢀⣴⠾⠟⠛⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀
*/
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...