题意:
有 n 个事件,在 A 会议室开会的时间段是 abegin aend, 在 B 会议室开会的时间段是bbegin bend。 现在的要求是在 A 会议室中任意事件相交,那么在 B 会议室中这些事件也要相交, 同理,在 B 会议室中任意事件相交,那么在 A 会议室中这些事件也要相交, 如果满足条件 输出 YES , 否则输出 NO。
思路:
对于所有的事件, 我们按照在 A 会议室中的时间顺序,将开始时间从小到大排序,那么 B 会议室中也要跟着排序,
然后 我们枚举 A 会议室中的每一个事件,由于起始时间是有序的, 所以我们可以找到一个区间,这个区间中的所有事件都与枚举的事件相交。 然后我们用线段树维护 B 会议室中的事件,把每个事件的起始时间和结束事件放到线段树中,找到这个区间中所有事件最小的结束时间,最大的开始时间, 看这两个时间和当前枚举事件的时间关系,判断是不是都相交。
如果存在 mx < begin || mn > end 那么就说明有不相交的, 就要输出 NO。
然后我们交换 A B 会议室中的事件内容, 重新做一遍。
反思:
做这道题的时候,完全没有想到要怎么做, 一开始想的是枚举 时间点,看有几个事件是覆盖这个事件点的, 然后去判断 B 会议室。
但是想着想着就不会了, 然后又想着怎么找几个事件他们是相交的,也没有想出来。
最终还是要枚举事件,
#include<bits/stdc++.h>
#define lson now << 1
#define rson now << 1 | 1
using namespace std;
const int N = 1e5+100;
void dbg() {cout << endl;}
template<typename T, typename... A> void dbg(T a, A... x) {cout << a << ' '; dbg(x...);}
#define logs(x...) {cout << #x << " -> "; dbg(x);}
int n,m;
struct node{
int a,b,c,d;
bool operator < (const node&A) const{
if (a != A.a) return a < A.a;
return b < A.b;
}
}f[N];
int mn[N*4],mx[N*4],ansmn,ansmx;
vector<int>g;
void build(int now, int l, int r){
if (l + 1 == r){
mx[now] = f[l-1].c;
mn[now] = f[l-1].d;
return;
}
int mid = (l + r) >> 1;
build(lson, l, mid); build(rson, mid, r);
mx[now] = max(mx[lson], mx[rson]);
mn[now] = min(mn[lson], mn[rson]);
}
void ask(int now, int l, int r, int a, int b){
if (a <= l && b >= r - 1){
ansmx = max(ansmx, mx[now]);
ansmn = min(ansmn, mn[now]);
return;
}
int mid = (l + r) >> 1;
if (a < mid) ask(lson, l, mid, a, b);
if (b >= mid) ask(rson, mid, r, a, b);
}
void solve(){
sort(f, f + n);
g.clear();
for (int i = 0;i < n; ++i)
g.push_back(f[i].a);
sort(g.begin(), g.end());
for (int i = 0; i < n* 4+10; ++i){
mx[i] = 0; mn[i] = 1e9+10;
}
build(1,1,n+1);
int L , R;
for (int i = 0; i < n; ++i){
L = i + 2; R = upper_bound(g.begin(), g.end(), f[i].b) - g.begin();
if (L > R) continue;
ansmx = 0; ansmn = 1e9+100;
ask(1,1,n+1,L, R);
if (ansmn < f[i].c || ansmx > f[i].d) {
// logs(i, ansmn, ansmx, f[i].a, f[i].b);
puts("NO");
exit(0);
}
}
}
int main(){
scanf("%d",&n);
for (int i = 0; i < n; ++i)
scanf("%d%d%d%d",&f[i].a,&f[i].b ,&f[i].c ,&f[i].d);
solve();
for (int i = 0; i < n; ++i){
swap(f[i].a, f[i].c);
swap(f[i].b, f[i].d);
}
solve();
puts("YES");
return 0;
}