Pairing Pairs

来个愉快的扫描线。

我们先按照题意,把不合法的情况画到平面直角坐标系上: 1710064201246.png 所有合法的情况都不应该出现在该直线上。另外,题目保证 ,所以所有的合法点都应该出现在直线 上方。

所有的合法的点出现的地方可以分成 6 个部分。我们进行 3 次扫描线:

  1. 沿 x 正方向,处理每个点 ➀➁➂ 的部分
  2. 沿 y 负方向,处理每个点 ➂➃➄ 的部分
  3. 沿 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;
}
posted @ 2024-03-10 18:02  MrPython  阅读(6)  评论(0)    收藏  举报  来源