Pairing Pairs
来个愉快的扫描线。
我们先按照题意,把不合法的情况画到平面直角坐标系上:
所有合法的情况都不应该出现在该直线上。另外,题目保证 ,所以所有的合法点都应该出现在直线 上方。
所有的合法的点出现的地方可以分成 6 个部分。我们进行 3 次扫描线:
- 沿 x 正方向,处理每个点 ➀➁➂ 的部分
- 沿 y 负方向,处理每个点 ➂➃➄ 的部分
- 沿 y 正方向,处理每个点 ➅ 的部分。
以第一次扫描为例,拿 multimap 存下所有扫过的点的 y 坐标和编号。使用 std::multimap::upper_bound 查找、判断三个区间内第一个点。接下来相信对于熟练掌握扫描线算法的同学没有任何难度了。
#include<bits/extc++.h>
using namespace std;
namespace pbds=__gnu_pbds;
using ui=unsigned int;
using uli=unsigned long long int;
using li=long long int;
int main(void){
ios::sync_with_stdio(false),cin.tie(nullptr),cout.tie(nullptr);
ui m;size_t n;cin>>m>>n;++m;
vector<pair<ui,ui>> a(n);
vector<size_t> ans(n,~0);
for (pair<ui,ui>& i:a) cin>>i.first>>i.second;
{ // 沿 x 轴方向从左到右扫,处理 ➀➁➂
vector<vector<pair<ui,size_t>>> s(m);
for (size_t i=0;i<n;++i) s[a[i].first].emplace_back(a[i].second,i);
multimap<ui,size_t> vis;
for (size_t i=0;i<m;++i){
for (pair<ui,size_t> const& j:s[i]){
// 当前点 x 坐标为 i, y 坐标为 j.first, 编号 j.second
multimap<ui,size_t>::const_iterator it;
it=vis.cbegin(); // ➀
if (it!=vis.cend()&&it->first<i) ans[j.second]=it->second;
it=vis.upper_bound(i); // ➁
if (it!=vis.end()&&it->first<j.first) ans[j.second]=it->second;
it=vis.upper_bound(j.first); // ➂
if (it!=vis.end()) ans[j.second]=it->second;
}
for (pair<ui,size_t> const& j:s[i])
vis.insert(j);
}
}{ // 沿 y 轴方向从上到下扫,处理 ➂➃➄
vector<vector<pair<ui,size_t>>> s(m);
for (size_t i=0;i<n;++i) s[a[i].second].emplace_back(a[i].first,i);
multimap<ui,size_t> vis;
for (size_t i=m-1;i<m;--i){
for (pair<ui,size_t> const& j:s[i]){
// 当前点 x 坐标为 j.first, y 坐标为 i, 编号 j.second
multimap<ui,size_t>::const_iterator it;
it=vis.cbegin(); // ➂
if (it!=vis.cend()&&it->first<j.first) ans[j.second]=it->second;
it=vis.upper_bound(j.first); // ➃
if (it!=vis.end()&&it->first<i) ans[j.second]=it->second;
it=vis.upper_bound(i); // ➄
if (it!=vis.end()) ans[j.second]=it->second;
}
for (pair<ui,size_t> const& j:s[i])
vis.insert(j);
}
}{ // 沿 y 轴方向从下到上扫,处理 ➅
vector<vector<pair<ui,size_t>>> s(m);
for (size_t i=0;i<n;++i) s[a[i].second].emplace_back(a[i].first,i);
multimap<ui,size_t> vis;
for (size_t i=0;i<m;++i){
for (pair<ui,size_t> const& j:s[i]){
// 当前点 x 坐标为 j.first, y 坐标为 i, 编号 j.second
multimap<ui,size_t>::const_iterator it;
it=vis.upper_bound(j.first); // ➅
if (it!=vis.end()) ans[j.second]=it->second;
}
for (pair<ui,size_t> const& j:s[i])
vis.insert(j);
}
}
for (size_t i:ans) cout<<i+1<<' ';
return 0;
}
浙公网安备 33010602011771号