标签:amp define using cto swa 维护 for ons script
给定 \(n\) 个区间对 \(([s_a,e_a],[s_b,e_b])\),求是否存在一个子集,使得子集中所有区间对的 \(first\) 区间对中互不相交和 \(second\) 区间对中互不相交二者恰好有一个成立。
考虑到如果存在一个满足条件的子集,那么一定存在一个满足条件的二元子集,因此找子集转化为找两个区间对,满足前项相交和后项相交不同时成立。
考虑前项相交而后项不相交的情况。对前项区间用扫描线扫描,那么当前维护的就是前项相交的所有区间,如果这些区间的最大左端点大于最小右端点,那么显然我们找到了一个这样的区间。
#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 - 扫描线
标签:amp define using cto swa 维护 for ons script
原文地址:https://www.cnblogs.com/mollnn/p/14002645.html