[ABC326C] Peak 题解

题意简述

给你 $n$ 个物品和他们的坐标 $a_i$,求坐标区间 $\left [ x,x+m \right ) $ 内的最大物品数量。

$\mathtt{problem.1}$ 区间枚举

最先想到的是标记坐标,然后按坐标枚举区间,取最大值。

这样绝对是会超时的。

不妨考虑从每个礼物的坐标出发,寻找 $\left [a_i,a_i+m \right)$ 中的元素个数。

这样的区间一定能包含一个物品,所以应该从他们出发,省去许多不必要的区间。

$\mathtt{problem.2}$ 快速求出这个区间中的元素个数

由于本题坐标值域很大,所以先对坐标排序,考虑每个区间中最后包含的元素是哪一个,然后就能 $O(1)$ 求出一个以物品坐标为左端点的区间物品个数。

即,求出第一个坐标小于 $a_i + m$ 并且大于等于 $a_i$ 的元素。

可以使用二分以 $O(\log n)$ 的时间复杂度解决。

Code

#include<bits/stdc++.h>
using namespace std;
int n, m;
int a[300010];
int main(){
    cin >> n >> m;
    for (int i = 1; i <= n; i ++){
        cin >> (a + i)[0];
    }
    sort(a + 1, a + 1 + n);
    int ans = 0;
    for (int i = 1; i <= n; i ++){
        int l = i, r = n;
        while(l < r){//二分找出第一个小于 a[i]-m 的数
            int mid = (l + r + 1) >> 1;
            if(a[mid] - a[i] >= m) r = mid - 1;
            else l = mid;
        }
        ans = max(ans, l - i + 1);
    }
    cout << ans << endl;
    return 0;
}

后言

其实此题有更优秀的方法,不算排序 $O(n)$ 解决的双指针做法。

但是我不会我要另辟蹊径。

posted @ 2023-11-01 16:42  固态H2O  阅读(4)  评论(0编辑  收藏  举报  来源