思路 :
- 从区间角度考虑
- 假设我们已经存下了所有区间,每次询问只要找到第一个大于等于当前时间t的右端点的区间;如果不存在,说明肯定Yes;如果存在,且左端点大于t,Yes,否则No
- 首先将所有区间输入,用map中的key作为区间右端点,对应的值为区间左端点;再用一个vector存下所有区间右端点后排序,这样我们既可以方便地找到第一个大于等于当前时间的右端点,还可以通过map找到对应的左端点
- 注意区间包含关系的合并!!!(不仅指右端点重合,还需要将完全包含的也要合并,否则lower_bound后很可能会出错)
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <deque>
#include <sstream>
#include <unordered_set>
#include <unordered_map>
#include <bitset>
#define endl '\n'
#define _(a) cout << #a << ": " << (a) << " "
#define one first
#define two second
#define pb push_back
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ll, int> pli;
typedef pair<int, ll> pil;
int n, h, m, q;
map<ll, ll> ma;
vector<ll> ed;
int main() {
ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
cin >> n >> h >> m >> q;
for (int i = 0; i < n; ++ i) {
ll a, b, c, d;
cin >> a >> b >> c >> d;
ll t1 = a * m + b;
ll t2 = c * m + d;
if (!ma.count(t2)) ma[t2] = t1;
else ma[t2] = min(ma[t2], t1);
ed.push_back(t2);
}
sort(ed.begin(), ed.end());
for (int i = (int)ed.size() - 1; i; -- i) {
if (ma[ed[i]] < ma[ed[i - 1]]) ma[ed[i - 1]] = ma[ed[i]];
}
while (q -- ) {
ll x, y;
cin >> x >> y;
ll t = x * m + y;
auto pos = lower_bound(ed.begin(), ed.end(), t);
if (pos == ed.end()) cout << "Yes" << endl;
else if (ma[*pos] > t) cout << "Yes" << endl;
else cout << "No" << endl;
}
}