[codeforces1284D]New Year and Conference 离散化+multiset【或排序+线段树】

【题目】:题目链接

time limit per test
2 seconds
memory limit per test
1024 megabytes
input
standard input
output
standard output

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

The conference will have nn lectures. Hyunuk has two candidate venues aa and bb. For each of the nn lectures, the speaker specified two time intervals [sai,eai][sai,eai] (saieaisai≤eai) and [sbi,ebi][sbi,ebi] (sbiebisbi≤ebi). If the conference is situated in venue aa, the lecture will be held from saisai to eaieai, and if the conference is situated in venue bb, the lecture will be held from sbisbi to ebiebi. 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][x,y] overlaps with a lecture held in interval [u,v][u,v] if and only if max(x,u)min(y,v)max(x,u)≤min(y,v).

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

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

A venue-sensitive set is problematic for a participant who is interested in attending the lectures in ss 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 nn (1n1000001≤n≤100000), the number of lectures held in the conference.

Each of the next nn lines contains four integers saisai, eaieai, sbisbi, ebiebi (1sai,eai,sbi,ebi1091≤sai,eai,sbi,ebi≤109, saieai,sbiebisai≤eai,sbi≤ebi).

Output

Print "YES" if Hyunuk will be happy. Print "NO" otherwise.

You can print each letter in any case (upper or lower).

Examples
input
Copy
2
1 2 3 6
3 4 7 8
output
Copy
YES
input
Copy
3
1 3 2 4
4 5 6 7
3 4 5 5
output
Copy
NO
input
Copy
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
Copy
YES
Note

In second example, lecture set {1,3}{1,3} is venue-sensitive. Because participant can't attend this lectures in venue aa, but can attend in venue bb.

In first and third example, venue-sensitive set does not exist.

 

【题意】

有n个演讲,两个场地。每个演讲可以在 [𝑠𝑎𝑖,𝑒𝑎𝑖] (𝑠𝑎𝑖≤𝑒𝑎𝑖)  时间段在a场地举行,或[𝑠𝑏𝑖,𝑒𝑏𝑖] (𝑠𝑏𝑖≤𝑒𝑏𝑖)时间段在b场地举行。

在同一个场地,两个会议时间分别为[x,y],[u,v]  如果 max(𝑥,𝑢)≤min(𝑦,𝑣)两个会议就冲突。

求任意两个会议要么同时在ab两地冲突,要么都不冲突(即如果在a冲突则在b也要冲突)

满足输出YES,不满足输出NO

【题解】

参考 xht37's blog

方法1:离散化+multiset

扫描时间轴,检查每一个时间点,在a场地发生的事件,则在b场地也应该都发生。

再做一遍,检查每一个时间点,在b场地发生的事件,在a场地也应该发生。

扫描过程:

因为要扫描时间,所以先对时间离散化

把每个时间a场地发生、终止的事件记录下来。

从前往后扫描,对于发生的事,把b事件的起始时间加到从大到小的multiset,终止时间加到从小到大的multiset;当前时间点b中事件两两冲突的条件时maxend>=minstar (事件之间没有间隔);终止的事从集合中删掉

一旦maxend<minstar,则输出NO.

ac代码

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int const maxn=100005;
 4 int sa[maxn],sb[maxn],ea[maxn],eb[maxn],a[maxn<<2],tot,m,n;
 5 vector<int>st[maxn<<2],en[maxn<<2];
 6 multiset<int>rmin;
 7 multiset<int,greater<int>>lmax;//默认从小到大
 8 bool work(){
 9     for(int i=1;i<=m;i++)st[i].clear(),en[i].clear();
10     for(int i=1;i<=n;i++)st[sa[i]].push_back(i),en[ea[i]].push_back(i);
11     rmin.clear(),lmax.clear();
12     for(int i=1;i<=m;i++){
13         for(int z:st[i]){lmax.insert(sb[z]);rmin.insert(eb[z]);}
14         if(lmax.size()&&*lmax.begin()>*rmin.begin())return 1;//取元素的值用 * 
15         for(int z:en[i])lmax.erase(lmax.find(sb[z])),rmin.erase(rmin.find(eb[z]));
16             //erase(pos) 会删掉这个位置的元素(只删1个);erase(element)删掉这个元素,返回删去元素个数(删掉了多个)
17     }
18     return 0;
19 }
20 inline int get_num(){
21     char ch=getchar();
22     int num=0;
23     while(ch<'0'||ch>'9'){ch=getchar();}
24     while(ch>='0'&&ch<='9'){num=(num<<1)+(num<<3)+ch-'0';ch=getchar();}
25     return num;
26 }
27 int main(){
28     scanf("%d",&n);
29     for(int i=1;i<=n;i++){
30         sa[i]=get_num(),ea[i]=get_num(),sb[i]=get_num(),eb[i]=get_num();
31         a[++tot]=sa[i];a[++tot]=ea[i];a[++tot]=sb[i];a[++tot]=eb[i];
32     }
33     sort(a+1,a+1+tot);
34     m=unique(a+1,a+1+tot)-a-1;
35     for(int i=1;i<=n;i++){
36         sa[i]=lower_bound(a+1,a+1+m,sa[i])-a;
37         ea[i]=lower_bound(a+1,a+1+m,ea[i])-a;
38         sb[i]=lower_bound(a+1,a+1+m,sb[i])-a;
39         eb[i]=lower_bound(a+1,a+1+m,eb[i])-a;
40     }
41     bool ans=work();
42     swap(sa,sb);swap(ea,eb);
43     if(ans||work())printf("NO\n");
44     else printf("YES\n");
45     return 0;
46 }

方法2:

参考博客:https://www.cnblogs.com/zsben991126/p/12155688.html

线段树+排序

要比上面用stl的方法快些

posted @ 2020-01-15 13:17  conver^_^  阅读(270)  评论(0编辑  收藏  举报