【set】 邻值查找

传送门

题意

给定一个长度为 \(n\) 的序列 \(A\)\(A\) 中的数各不相同。对于 \(A\) 中的每一个数 \(A_{i}\),求\(min| A_{i} − A_{j} | \: (1 \leq j < i )\)
以及令上式取到最小值的 \(j\)(记为 \(P_{i}\))。若最小值点不唯一,则选择使 \(A_{j}\) 较小的那个。

数据范围

\(n \leq 10^{5}\)
\(|A_{i}|\leq 10^{9}\)

题解

  • 因为set内部是平衡二叉树,每次插入都保持有序,首先保证差的绝对值最小然后取位于前面的,所以先算后面的
  • 再判断如果值相同或更小更新为前面的

Code

#include <bits/stdc++.h>
#define pii pair<int,int>
#define fi first
#define se second
using namespace std;
set<pii>s;
int main(){
   int n,a;
   cin>>n>>a;
   s.insert({a,1});
   for(int i=2;i<=n;i++){
      int x;
      cin>>x;
      s.insert( { x , i } );
      auto it = s.find({x, i});
      pii ans;
      ans.fi=INT_MAX;//当只有一个元素时用于判断
      auto it_=it;
      if(++it_ != s.end())//set的end不指向任何一个元素,是个标志,如果当前是end证明x没有后继
         ans = {it_->fi - x,it_->se};
      if(it -- != s.begin() && ans.fi >= x - it->fi)//当前不是开头证明前面有比他小的
         ans = { x - it->fi,it->se};
      cout<<ans.fi<<' '<<ans.se<<endl;
   }
}
posted @ 2020-05-28 17:56  Hyx'  阅读(220)  评论(0)    收藏  举报