[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)$ 解决的双指针做法。
但是我不会我要另辟蹊径。