题解:AT_abc457_e [ABC457E] Crossing Table Cloth
Jason20090916 · · 题解
对于成功的情况进行分讨。
- 使用两张布拼起来。
- 一张布恰好完全覆盖,再随意选一张被完全包含在
[S, T] 内的布。
对于第一种情况,选的布里面肯定有一张的左端点在
分别记录下以
对于第二种情况,我们可以将询问离线下来,从大到小枚举
注意这是一个格子覆盖问题而非线段覆盖问题,存在
#include<bits/stdc++.h>
#define ll long long
#define pii pair<int, int>
#define fi first
#define se second
using namespace std;
const int MAXN = 2e5 + 9;
int n, m, q;
string ans[MAXN];
vector<pii> vl[MAXN], vr[MAXN];
pair<pii, int> nq[MAXN];
struct FWT {
int t[MAXN];
int lowbit(int x) {
return x & (-x);
}
void add(int x, int v) {
while(x <= n) {
t[x] += v;
x += lowbit(x);
}
}
int query(int x) {
int res = 0;
while(x) {
res += t[x];
x -= lowbit(x);
}
return res;
}
} fwt;
void solve() {
cin >> n >> m;
for(int i = 1; i <= m; i++) {
int l, r;
cin >> l >> r;
vl[r].push_back({l, i});
vr[l].push_back({r, i});
}
cin >> q;
for(int i = 1; i <= q; i++) {
cin >> nq[i].fi.fi >> nq[i].fi.se;
nq[i].se = i;
}
for(int i = 1; i <= n; i++) sort(vr[i].begin(), vr[i].end()), sort(vl[i].begin(), vl[i].end());
sort(nq + 1, nq + q + 1);
for(int i = q, lst = n + 1; i; i--) {
int ql = nq[i].fi.fi, qr = nq[i].fi.se, id = nq[i].se;
while(lst > ql) {
lst--;
for(auto it : vr[lst]) fwt.add(it.fi, 1);
}
bool flag1 = 0, flag2 = 0;
auto itl = upper_bound(vr[ql].begin(), vr[ql].end(), (pii){qr, m + 1});
if(itl != vr[ql].begin()) {
itl--;
flag1 = 1;
}
auto itr = lower_bound(vl[qr].begin(), vl[qr].end(), (pii){ql, 0});
if(itr != vl[qr].end()) flag2 = 1;
if(!flag1 || !flag2) ans[id] = "No";
else if(itl -> se != itr -> se) {
if(itl -> fi + 1 >= itr -> fi) ans[id] = "Yes";
else ans[id] = "No";
}
else {
if(fwt.query(qr) >= 2) ans[id] = "Yes";
else ans[id] = "No";
}
}
for(int i = 1; i <= q; i++) cout << ans[i] << '\n';
return;
}
int main() {
solve();
return 0;
}
::::