[CF1284D] New Year and Conference - 扫描线
Posted mollnn
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[CF1284D] New Year and Conference - 扫描线相关的知识,希望对你有一定的参考价值。
Description
给定 (n) 个区间对 (([s_a,e_a],[s_b,e_b])),求是否存在一个子集,使得子集中所有区间对的 (first) 区间对中互不相交和 (second) 区间对中互不相交二者恰好有一个成立。
Solution
考虑到如果存在一个满足条件的子集,那么一定存在一个满足条件的二元子集,因此找子集转化为找两个区间对,满足前项相交和后项相交不同时成立。
考虑前项相交而后项不相交的情况。对前项区间用扫描线扫描,那么当前维护的就是前项相交的所有区间,如果这些区间的最大左端点大于最小右端点,那么显然我们找到了一个这样的区间。
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1000005;
struct Range
{
int l, r;
};
struct Event
{
int tim;
int flag;
Range range;
bool operator<(const Event &b)
{
if(tim != b.tim) return tim < b.tim;
else return flag < b.flag;
}
};
int n;
vector<pair<Range, Range>> src;
bool solve()
{
vector<Event> vec;
for (auto i : src)
{
vec.push_back({i.first.l, 0, i.second});
vec.push_back({i.first.r, 1, i.second});
}
sort(vec.begin(), vec.end());
multiset<int> sl, sr;
for (auto e : vec)
{
if (e.flag == 0)
{
sl.insert(e.range.l);
sr.insert(e.range.r);
}
else
{
sl.erase(sl.find(e.range.l));
sr.erase(sr.find(e.range.r));
}
if (sl.size() && *sl.rbegin() > *sr.begin())
{
return false;
}
}
return true;
}
signed main()
{
ios::sync_with_stdio(false);
cin >> n;
for (int i = 1; i <= n; i++)
{
int t1, t2, t3, t4;
cin >> t1 >> t2 >> t3 >> t4;
src.push_back({{t1, t2}, {t3, t4}});
}
int ans = solve();
for (auto &i : src)
{
swap(i.first, i.second);
}
ans &= solve();
cout << (ans ? "YES" : "NO") << endl;
}
以上是关于[CF1284D] New Year and Conference - 扫描线的主要内容,如果未能解决你的问题,请参考以下文章
CF 750C New Year and Rating(思维题)
CF1284E New Year and Castle Construction
CF1284E New Year and Castle Construction
CF1279F New Year and Handle Change 题解