題解/算法 {2940. 找到 Alice 和 Bob 可以相遇的建筑}

題解/算法 {2940. 找到 Alice 和 Bob 可以相遇的建筑}

@LINK: https://leetcode.cn/problems/find-building-where-alice-and-bob-can-meet/;

對於一個查詢(a,b):
@IF(a==bH[ min(a,b)] < H[ max(a,b)]): 此時答案就是max(a,b);
@ELSE: 你需要在H[ max(a,b), ....] 這個後綴裡 找第一個滿足> max( H[a], H[b])的元素;
. 做離線化處理, 即對查詢 根據max(a,b) 從大到小排序, 這樣 我們全局維護H[ max(a,b),...]這個元素;
. 問題轉換為 對於[a1, a2, a3, ...] 找從左到右 第一個>x的元素;
. 看一個錯誤做法, ai放到set裡, 然後upper_bound(x); 這是錯誤的 比如[5, 3, 7] 如果找upper_bound(1) 則你會找到3 而答案是5;
. 正確做法: 對於[5(a), 5(b), 3, 7] 使用單調棧思想 變成[5(a), 7]嚴格遞增序列, 當你讓set裡放到一個x時 如果set.begin() <= x 則把set.erase( set.begin()), 不用考慮index 因為當前x元素的下標 一定< set裡所有元素的index;
. 然後答案為: set>x的第一個元素, 由於set的元素是pair<int,int>(val, index), 如果你寫成upper_bound(x, -1) 這是錯誤的 因為可能找到是(x, ?) 即第二維度會起作用 顯然這個元素並不滿足條件 因為我們要的是(>x, ?), 正確答案是 upper_bound( {x, 1e9}) 讓第二維度最大 那麼找到的答案 一定是(>x, ?);

vector<int> leftmostBuildingQueries(vector<int>& H, vector<vector<int>>& Q) {
  int N = H.size();
  using T_ = tuple<int,int,int>;
  vector< T_> Que( Q.size());
  FOR_( i, 0, Q.size()-1){ Que[i] = {Q[i][0], Q[i][1], i};}
  sort( Que.begin(), Que.end(), []( auto _a, auto _b){ 
    return max(get<0>(_a), get<1>(_a)) > max(get<0>(_b), get<1>(_b)); });
  vector<int> ANS( Q.size());
  set< pair<int,int> > S;
  int nn = N;
  for( auto que : Que){
      int a = get<0>(que), b = get<1>(que);
      auto & curANS = ANS[ get<2>(que)];
      if( a > b){ swap(a,b);}
      if( H[a]<H[b] || a==b){ // 特判
          curANS = b;
          continue;
      }

      while( nn > max(a,b)){
          -- nn;
          while( !S.empty() && S.begin()->first <= H[nn]){ S.erase( S.begin());} // 單調棧
          S.insert( {H[nn], nn});
      }
      auto it = S.upper_bound( {max(H[a], H[b]), 1e9});
      if( it == S.end()){ curANS = -1;}
      else{ curANS = it->second;}
  }
  return ANS;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值