SP9734 题解
\(\color{red}{see}\space \color{green}{in}\space \color{blue}{my}\space \color{purple}{blog}\)
小学生又双叒叕来写题解啦!
看到 \(n \le 10^5\) 这一数据范围,容易想到时间复杂度可能是 \(O(n\log n)\) 没错吧。
首先对数组排序,可以使用 STL 中提供的 sort()
排序,由于使用简单,这里就不再赘述了哈。
然后,枚举每一个数 \(a_i\) 并用二分计算有多少个值为 \((a_i + k)\) 的元素。
这里,我们使用 STL 中的二分函数:lower_bound()
与 upper_bound()
。
其中,lower_bound()
求第一个小于某数的下标。
相反地,upper_bound()
求第一个小于等于某数的下标。
上面两个函数的时间复杂度都是 \(O(\log n)\)。
注意,使用时数组必须是从小到大的,这也是开头排序的原因。
更具体的用法请参见代码。
那么如何计算个数呢,用 upper_bound() - lower_bound()
就好了。
满分代码
由于上面讲得很清楚了,所以并没有添加注释,毕竟码量本身也超级小。
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int a[100005], n, k, cnt;
int main()
{
scanf("%d%d", &n, &k);
for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
sort(a+1, a+n+1);
for (int i = 1; i <= n; i++) cnt += (upper_bound(a+1, a+n+1, a[i] + k) - a) - (lower_bound(a+1, a+n+1, a[i] + k) - a);
printf("%d", cnt);
return 0;
}
首发:2022-04-09 23:20:42