Submission #1368589

#TimeUsernameProblemLanguageResultExecution timeMemory
1368589marcus06Examination (JOI19_examination)C++20
100 / 100
759 ms62652 KiB
/**
 * author:      marcus06
 * created:     09-05-2026 12:53:45
**/
#include <bits/stdc++.h>
using namespace std;
using lli = long long;

struct fenwick_tree {
    int n;
    vector <int> t;
    fenwick_tree() {}
    fenwick_tree(int _n): n(_n) {
        t.resize(n + 5);
    }
    void update(int x, int value) {
        for (; x <= n; x += x & -x) t[x] += value;
    }
    int query(int x) {
        int res = 0;
        for (; x > 0; x -= x & -x) res += t[x];
        return res;
    }
};

const int N = int(2e5) + 5;

vector <int> pos[N];
fenwick_tree BIT[N];
void fakeAdd(int u, int v, int x, int n) {
    x = x;
    for (; u <= n; u += u & -u) {
        pos[u].push_back(v);
    }
}
void fakeQuery(int u, int v) {
    for (; u > 0; u -= u & -u) {
        pos[u].push_back(v);
    }
}
void fakeRangeQuery(int x, int y, int u, int v) {
    fakeQuery(u, v);
    if (x > 1) fakeQuery(x - 1, v);
    if (y > 1) fakeQuery(u, y - 1);
    if (x > 1 && y > 1) fakeQuery(x - 1, y - 1);
}
void compressBIT(int n) {
    for (int i = 1; i <= n; ++i) {
        pos[i].push_back(0);
        sort(pos[i].begin(), pos[i].end());
        pos[i].erase(unique(pos[i].begin(), pos[i].end()), pos[i].end());
        BIT[i] = fenwick_tree(pos[i].size());
    }
}

void add(int u, int v, int x, int n) {
    for (int i = u; i <= n; i += i & -i) {
        int id = lower_bound(pos[i].begin(), pos[i].end(), v) - pos[i].begin();
        BIT[i].update(id, x);
    }
}
int query(int u, int v) {
    int res = 0;
    for (int i = u; i > 0; i -= i & -i) {
        int id = lower_bound(pos[i].begin(), pos[i].end(), v) - pos[i].begin();
        res += BIT[i].query(id);
    }
    return res;
}
int rangeQuery(int x, int y, int u, int v) {
    int res = query(u, v);
    if (x > 1) res -= query(x - 1, v);
    if (y > 1) res -= query(u, y - 1);
    if (x > 1 && y > 1) res += query(x - 1, y - 1);
    return res;
}

template <typename T>
void removeDuplicate(vector <T> &v) {
    sort(v.begin(), v.end());
    v.erase(unique(v.begin(), v.end()), v.end());
}

void solve() {
    int N, Q;
    cin >> N >> Q;

    vector <int> row_vals, col_vals;
    vector <pair <int, int>> A(N);
    for (int i = 0; i < N; ++i) {
        cin >> A[i].first >> A[i].second;
        row_vals.push_back(A[i].second);
        col_vals.push_back(A[i].first + A[i].second);
    }
    sort(A.begin(), A.end(), greater <pair <int, int>>());

    vector <array <int, 4>> queries(Q);
    for (int i = 0; i < Q; ++i) {
        for (int j = 0; j < 3; ++j) cin >> queries[i][j];
        queries[i][3] = i;
        row_vals.push_back(queries[i][1]);
        col_vals.push_back(queries[i][2]);
    }
    sort(queries.begin(), queries.end(), greater <array <int, 4>>());

    removeDuplicate(row_vals);
    removeDuplicate(col_vals);
    auto row_id = [&](int v) {
        return lower_bound(row_vals.begin(), row_vals.end(), v) - row_vals.begin() + 1;
    };
    auto col_id = [&](int v) {
        return lower_bound(col_vals.begin(), col_vals.end(), v) - col_vals.begin() + 1;
    };
    int rowSize = row_vals.size(), colSize = col_vals.size();

    //generate query
    int j = 0;
    for (int i = 0; i < Q; ++i) {
        auto [X, Y, Z, id] = queries[i];
        while (j < N && A[j].first >= X) {
            int x = row_id(A[j].second), y = col_id(A[j].first + A[j].second);
            fakeAdd(x, y, 1, rowSize);
            j++;
        }
        int x = row_id(Y), y = col_id(Z);
        fakeRangeQuery(x, y, rowSize, colSize);
    }

    compressBIT(rowSize);
    vector <int> ans(Q);
    j = 0;
    for (int i = 0; i < Q; ++i) {
        auto [X, Y, Z, id] = queries[i];
        while (j < N && A[j].first >= X) {
            int x = row_id(A[j].second), y = col_id(A[j].first + A[j].second);
            // cout << "ADD: " << A[j].second << ' ' << A[j].first + A[j].second << endl;
            add(x, y, 1, rowSize);
            j++;
        }
        int x = row_id(Y), y = col_id(Z);
        // cout << "QUERY: " << Y << ' ' << Z << " ID: " << id << endl;
        // cout << "GOT: " << query(x, y) << endl;
        ans[id] = rangeQuery(x, y, rowSize, colSize);
    }
    for (int i = 0; i < Q; ++i) {
        cout << ans[i] << '\n';
    }
}

int main() {
    std::cin.tie(0)->sync_with_stdio(0);
#ifdef LOCAL
    auto begin = std::chrono::high_resolution_clock::now();
#endif

    int tt = 1;
    while (tt--) {
        solve();
    }

#ifdef LOCAL
    auto end = std::chrono::high_resolution_clock::now();
    auto elapsed = std::chrono::duration_cast<std::chrono::nanoseconds>(end - begin);
    std::cerr << "Time measured: " << elapsed.count() * 1e-9 << " seconds.\n";
#endif
    return 0;
}
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...
#Result Execution timeMemoryGrader output
Fetching results...