CodeForces_1284D New Year and Conference(线段树、ST表)

New Year and Conference

time limit per test:2 seconds
memory limit per test:1024 megabytes
Problem Description

Filled with optimism, Hyunuk will host a conference about how great this new year will be!

The conference will have n lectures. Hyunuk has two candidate venues a and b. For each of the n lectures, the speaker specified two time intervals [ s a i , e a i ] [sa_i,ea_i] [sai,eai](sai≤eai) and [ s b i , e b i ] [sb_i,eb_i] [sbi,ebi] (sbi≤ebi). If the conference is situated in venue a, the lecture will be held from sai to eai, and if the conference is situated in venue b, the lecture will be held from sbi to ebi. Hyunuk will choose one of these venues and all lectures will be held at that venue.

Two lectures are said to overlap if they share any point in time in common. Formally, a lecture held in interval [x,y] overlaps with a lecture held in interval [u,v] if and only if max(x,u)≤min(y,v).

We say that a participant can attend a subset s of the lectures if the lectures in s do not pairwise overlap (i.e. no two lectures overlap). Note that the possibility of attending may depend on whether Hyunuk selected venue a or venue b to hold the conference.

A subset of lectures s is said to be venue-sensitive if, for one of the venues, the participant can attend s, but for the other venue, the participant cannot attend s.

A venue-sensitive set is problematic for a participant who is interested in attending the lectures in s because the participant cannot be sure whether the lecture times will overlap. Hyunuk will be happy if and only if there are no venue-sensitive sets. Determine whether Hyunuk will be happy.

Input

The first line contains an integer n ( 1 n 100000), the number of lectures held in the conference.

Each of the next n lines contains four integers sai, eai, sbi, ebi (1 sai,eai,sbi,ebi 109, sai eai ,sbiebi).

Output

Print “YES” if Hyunuk will be happy. Print “NO” otherwise.
You can print each letter in any case (upper or lower).

Sample Input

2
1 2 3 6
3 4 7 8

Sample Output

YES

题意

有n场表演,有两个场地,如果在a场地表演则需要占用 [ s a i , e a i ] [sai,eai] [sai,eai]这段时间,在b场地表演则需要占用 [sbi,ebi] 这段时间。如果两个表演,占用了同一个时间点,则认为这两个表演是冲突的。但因为每个表演在a场地和b场地的时间段不同,有表演可能在一个场地冲突而在另一个不冲突。所以所有的表演是否满足一起在某场地冲突或者不冲突。

题解:

题目就是让求两个表演,如果在a场地冲突,则在b场地也需要冲突,如果每两个表演都满足上述条件,则输出YES,否则输出NO。显然如果暴力判断,时间复杂度是 O ( n 2 ) O(n^2) O(n2),会超时。所以考虑对于第i个表演,找出 a 场地与它冲突的表演,然后判断这些表演在 b 场地是否也与其冲突。
对于表演 [ s 1 , e 1 ] [s_1,e_1] [s1,e1] [ x , y ] [x,y] [x,y],两者不冲突的条件是 e 1 < x ∣ ∣ s 1 > y e_1<x || s_1>y e1<xs1>y。而对于多个表演 [ s 1 , e 1 ] [s_1,e_1] [s1,e1] [ s 2 , e 2 ] [s_2,e_2] [s2,e2]…都与 [ x , y ] [x,y] [x,y]冲突,则需要不存在 e i < x ∣ ∣ s i > y e_i<x || s_i>y ei<xsi>y。所以如果 e m i n < x ∣ ∣ s m a x > y e_{min}<x || s_{max}>y emin<xsmax>y成立,则存在表演与 [ x , y ] [x,y] [x,y]不冲突。
可以考虑对 s 作为第一关键字,e 作为第二关键字升序排列。对于第 i 场表演,找出所有在 [ s a i , e a i ] [s_{ai},e_{ai}] [sai,eai]内开始的表演,则这些表演必然与第 i 场表演冲突。同时,排序过后的这些表演必然连续,可以考虑使用数据结构(线段树/ST表等)查询这一段区间另一个场地的eminsmax,如果另一个场地,有表演与第 i 个表演不冲突,则输出NO。
同时,因为上述只检验了在a场地冲突一定在b场地冲突的情况,并未考虑在b场地冲突而在a场地不冲突的情况。所以可以将[sai,eai]与[sbi,ebi]交换,再进行一次上述检验即可。

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#include<ctype.h>
#include<cstring>
#include<vector>
#include<queue>
#include<map>
#include<iterator>
#define dbg(x) cout<<#x<<" = "<<x<<endl;
#define INF 0x3f3f3f3f
#define eps 1e-6
 
using namespace std;
typedef long long LL;
typedef pair<int, int> P;
const int maxn = 100100;
const int mod = 9901;
struct node{
	int sa, ea, sb, eb;
	node(){}
	node(int a, int b, int c, int d){
		sa=a,ea=b,sb=c,eb=d;
	}
	bool operator <(node b)const{
		if(sa == b.sa)return ea < b.ea;
		return sa < b.sa;
	}
}p[maxn];
int mx[4*maxn], mi[4*maxn];
bool solve(int n);
void creat(int l, int r, int k);
int querymin(int l, int r, int al, int ar, int k);
int querymax(int l, int r, int al, int ar, int k);

int main()
{
	int n, i, j, k, sig = 1;
	scanf("%d", &n);
	for(i=1;i<=n;i++)
		scanf("%d %d %d %d", &p[i].sa, &p[i].ea, &p[i].sb, &p[i].eb);
	sig &= solve(n);
	for(i=1;i<=n;i++)
		swap(p[i].sa, p[i].sb), swap(p[i].ea, p[i].eb);
	sig &= solve(n);
	if(sig)printf("YES\n");
	else printf("NO\n");
	return 0;
}

bool solve(int n)
{
	sort(p+1, p+1+n);
	creat(1, n, 1);
	for(int i=1;i<=n;i++)
	{
		//查找与第i场表演冲突的集合
		int pos = lower_bound(p+1, p+1+n, node(p[i].ea, 1e9+1000, 0, 0) )-p-1;
		if(!(i+1 <= pos))continue;
		//检验另一场地中的所有表演是否都与当前场冲突
		if(querymin(1, n, i+1, pos, 1)<p[i].sb || 
			querymax(1, n, i+1, pos, 1)>p[i].eb)
			return false;
	}
	return true;
}
//线段树初始化,以及后面的函数求smax, emin。
void creat(int l, int r, int k)
{
	if(l == r){
		mx[k]=p[l].sb, mi[k]=p[l].eb;
		return ;
	}
	int mid = (l+r)/2;
	creat(l, mid, 2*k);
	creat(mid+1, r, 2*k+1);
	mx[k] = max(mx[2*k], mx[2*k+1]);
	mi[k] = min(mi[2*k], mi[2*k+1]);
}

int querymin(int l, int r, int al, int ar, int k)
{
	if(l == al && r == ar)return mi[k];
	int mid = (l+r)/2;
	if(ar <= mid)return querymin(l, mid, al, ar, 2*k);
	else if(al > mid)return querymin(mid+1, r, al, ar, 2*k+1);
	else return min(querymin(l, mid, al, mid, 2*k),
					querymin(mid+1, r, mid+1, ar, 2*k+1));
}

int querymax(int l, int r, int al, int ar, int k)
{
	if(l == al && r == ar)return mx[k];
	int mid = (l+r)/2;
	if(ar <= mid)return querymax(l, mid, al, ar, 2*k);
	else if(al > mid)return querymax(mid+1, r, al, ar, 2*k+1);
	else return max(querymax(l, mid, al, mid, 2*k),
					querymax(mid+1, r, mid+1, ar, 2*k+1));
}
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值