Loading

【做题笔记】板刷 AtCoder

[ABC364D] K-th Nearest

很好想的题目。

首先可以考虑到答案具有单调性,所以对于每一次询问用二分处理即可。

然后考虑如何判合法。我们需要找到所有 \(a_i-b\)\(\le x\)\(\ge -x\) 的个数。可以现将 \(a_i\) 排好序,最后用两个二分统计个数看是否 \(\ge k\) 即可。

时间复杂度 \(O(q \log^2 n)\)

点击查看代码
#include <bits/stdc++.h>
#define int long long
#define rint register int
#define For(i,l,r) for(rint i=l;i<=r;++i)
#define FOR(i,r,l) for(rint i=r;i>=l;--i)

using namespace std;

const int N = 2e5 + 10;

int n, q, a[N], k, b;

bool check(int x) {
  int L = n+1, R = 0;
  int l = 1, r = n;
  while(l <= r) {
    int mid = l + r >> 1;
    if(a[mid] - b <= x) {
      R = mid;
      l = mid + 1;
    } else {
      r = mid - 1;
    }
  }
  l = 1, r = n;
  while(l <= r) {
    int mid = l + r >> 1;
    if(a[mid] - b >= -x) {
      L = mid;
      r = mid - 1;
    } else {
      l = mid + 1;
    }
  }
  return (R-L+1) >= k;
}

signed main() {
  ios::sync_with_stdio(0);
  cin.tie(0), cout.tie(0);
  cin >> n >> q;
  For(i,1,n) cin >> a[i];
  sort(a + 1, a + n + 1);
  while(q--) {
    int l = 0, r = 2e8, ans = 0;
    cin >> b >> k;
    while(l <= r) {
      int mid = l + r >> 1;
      if(check(mid)) {
        ans = mid;
        r = mid - 1;
      } else {
        l = mid + 1;
      }
    }
    cout << ans << '\n';
  }
  return 0;
}
posted @ 2024-08-05 17:44  Daniel_yzy  阅读(4)  评论(0编辑  收藏  举报