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

posted @ 2022-08-25 00:30  liangbowen  阅读(3)  评论(0编辑  收藏  举报