Codeforces —— New Year and Conference(1284D)


input

2
1 2 3 6
3 4 7 8

output

YES

input

3
1 3 2 4
4 5 6 7
3 4 5 5

output

NO

input

6
1 5 2 9
2 4 5 8
3 6 7 11
7 10 12 16
8 11 13 17
9 12 14 18

output

YES

题意

一共有A,B两个会议场,每个会议场会有n场会议,每次给出在A和B会议场进行的第i场会议的时间段
现要求从中任选出k(k>=2)场会议,这k场会议中在A会议场中的状态(向交与否)与在B会议场中的
状态必须相同

思路

第三组样例:

在会议场A中对于一个会议i我们可以二分查找出与它冲突的所有会议,令该会议时间段的集合为S,在B中判断S时间
段的有没有与i区间不相交,若有则不满足题意,之后再反向操作一遍即可
其中判断一个集合中的时间段是否与i区间相交可以用线段树维护区间最值

代码

#pragma GCC optimize(2)
#include<iostream>
#include<unordered_map>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<string>
#include<vector>
#include<queue>
#include<stack>
#include<cmath>
#include<map>
#include<set>
#define Buff ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define rush() int Case = 0; int T; cin >> T;  while(T--)
#define rep(i, a, b) for(int i = a; i <= b; i ++)
#define per(i, a, b) for(int i = a; i >= b; i --)
#define reps(i, a, b) for(int i = a; b; i ++)
#define clc(a, b) memset(a, b, sizeof(a))
#define Buff ios::sync_with_stdio(false)
#define readl(a) scanf("%lld", &a)
#define readd(a) scanf("%lf", &a)
#define readc(a) scanf("%c", &a)
#define reads(a) scanf("%s", a)
#define read(a) scanf("%d", &a)
#define lowbit(n) (n&(-n))
#define pb push_back
#define sqr(x) x*x
#define lson rt<<1
#define rson rt<<1|1
#define ls lson, l, mid
#define rs rson, mid+1, r
#define y second
#define x first
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int>PII;
const int mod = 1e9+7;
const double eps = 1e-6;
const int N = 1e5+7;
int Max[N<<2], Min[N<<2];
int n;
struct node
{
    int sa, ea, sb, eb;
    bool operator < (node t)const{
        if(sa == t.sa)  return ea < t.ea;
        return sa < t.sa;
    }
}p[N];
void build(int rt, int l, int r)
{
    if(l == r)
    {
        Max[rt] = p[l].sb;
        Min[rt] = p[l].eb;
        return ;
    }
    int mid = l + r >> 1;
    build(ls);  build(rs);
    Max[rt] = max(Max[lson], Max[rson]);
    Min[rt] = min(Min[lson], Min[rson]);
}
int QueryMax(int rt, int l, int r, int L, int R)
{
    if(l >= L && r <= R)    return Max[rt];
    int mid = l + r >> 1;
    if(R <= mid)        return QueryMax(ls, L, R);
    else if(L > mid)    return QueryMax(rs, L, R);
    else                return max(QueryMax(ls, L, mid), QueryMax(rs, mid+1, R));
}
int QueryMin(int rt, int l, int r, int L, int R)
{
    if(l >= L && r <= R)    return Min[rt];
    int mid = l + r >> 1;
    if(R <= mid)        return QueryMin(ls, L, R);
    else if(L > mid)    return QueryMin(rs, L, R);
    else                return max(QueryMin(ls, L, mid), QueryMin(rs, mid+1, R));
}
bool judge()
{
    sort(p+1, p+n+1);
    build(1, 1, n);
    rep(i, 1, n)
    {
        node t = {p[i].ea, mod, 0, 0};
        int pos = lower_bound(p+1, p+n+1, t) - p - 1;
        if(pos <= i)  continue;
        int minv = QueryMin(1, 1, n, i+1, pos);
        int maxv = QueryMax(1, 1, n, i+1, pos);
        if(maxv > p[i].eb || minv < p[i].sb)    return false;
    }
    return true;
}
int main()
{
    cin >> n;
    rep(i, 1, n)
    {
        int a, b, c, d;
        cin >> a >> b >> c >> d;
        p[i] = {a, b, c, d};
    }
    int res = 0;
    if(judge()) res ++;
    rep(i, 1, n)
    {
        swap(p[i].sa, p[i].sb);
        swap(p[i].ea, p[i].eb);
    }
    if(judge()) res ++;
//    cout << res <<endl;
    puts(res == 2 ? "YES" : "NO");
	return 0;
}
原文地址:https://www.cnblogs.com/Farrell-12138/p/13844229.html