제출 #1347805

#제출 시각아이디문제언어결과실행 시간메모리
1347805imaiTrampoline (info1cup20_trampoline)C++20
100 / 100
357 ms30032 KiB
#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define pb push_back
#define all(s) s.begin(),s.end()

const int MAXN = 200005;
const int LOG = 19;

struct Cell {
    int r, c, id;
};

bool compareCells(const Cell& a, const Cell& b) {
    if (a.r != b.r) return a.r < b.r;
    return a.c < b.c;
}

int up[MAXN][LOG];
vector<int> row_coords;
vector<Cell> green_cells;
vector<int> cells_in_row[MAXN];

int get_row_idx(int r) {
    auto it = lower_bound(all(row_coords), r);
    if (it != row_coords.end() && *it == r) 
        return distance(row_coords.begin(), it);
    return -1;
}

void solve() {
    int R, C, N;
    if (!(cin >> R >> C >> N)) return;

    green_cells.resize(N);
    for (int i = 0; i < N; i++) {
        cin >> green_cells[i].r >> green_cells[i].c;
        row_coords.pb(green_cells[i].r);
    }

    // Coordinate compress rows and sort cells
    sort(all(row_coords));
    row_coords.erase(unique(all(row_coords)), row_coords.end());
    sort(all(green_cells), compareCells);

    for (int i = 0; i < N; i++) {
        green_cells[i].id = i;
        cells_in_row[get_row_idx(green_cells[i].r)].pb(i);
    }

    // Precompute binary lifting (jumping to row r + 1)
    for (int i = 0; i < N; i++) {
        int next_row_val = green_cells[i].r + 1;
        int next_row_idx = get_row_idx(next_row_val);

        if (next_row_idx == -1) {
            up[i][0] = -1;
        } else {
            // Find first cell in next row with column >= current column
            int low = 0, high = cells_in_row[next_row_idx].size() - 1;
            int best_cell_idx = -1;
            while (low <= high) {
                int mid = low + (high - low) / 2;
                int cell_ptr = cells_in_row[next_row_idx][mid];
                if (green_cells[cell_ptr].c >= green_cells[i].c) {
                    best_cell_idx = cell_ptr;
                    high = mid - 1;
                } else {
                    low = mid + 1;
                }
            }
            up[i][0] = best_cell_idx;
        }
    }

    // Build the sparse table
    for (int j = 1; j < LOG; j++) {
        for (int i = 0; i < N; i++) {
            if (up[i][j - 1] != -1)
                up[i][j] = up[up[i][j - 1]][j - 1];
            else
                up[i][j] = -1;
        }
    }

    int T;
    cin >> T;
    while (T--) {
        int x1, y1, x2, y2;
        cin >> x1 >> y1 >> x2 >> y2;

        if (x1 == x2) {
            cout << (y1 <= y2 ? "Yes" : "No") << "\n";
            continue;
        }

        int start_row_idx = get_row_idx(x1);
        if (start_row_idx == -1) {
            cout << "No\n";
            continue;
        }

        // Find first green cell in row x1 with col >= y1
        int low = 0, high = cells_in_row[start_row_idx].size() - 1;
        int curr_cell = -1;
        while (low <= high) {
            int mid = low + (high - low) / 2;
            int cell_ptr = cells_in_row[start_row_idx][mid];
            if (green_cells[cell_ptr].c >= y1) {
                curr_cell = cell_ptr;
                high = mid - 1;
            } else {
                low = mid + 1;
            }
        }

        if (curr_cell == -1) {
            cout << "No\n";
            continue;
        }

        // Jump x2 - x1 - 1 times to reach row x2-1
        int jumps = x2 - x1 - 1;
        for (int j = 0; j < LOG; j++) {
            if ((jumps >> j) & 1) {
                if (curr_cell != -1) curr_cell = up[curr_cell][j];
            }
        }

        // Final check: From the green cell in row x2-1, 
        // we jump to row x2 at the same column. That column must be <= y2.
        if (curr_cell != -1 && green_cells[curr_cell].c <= y2) {
            cout << "Yes\n";
        } else {
            cout << "No\n";
        }
    }
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    solve();
    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...
#Verdict Execution timeMemoryGrader output
Fetching results...