如何用二分法查找一个长尾词在有序数组中的位置?

2026-04-12 03:502阅读0评论SEO资源
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计594个文字,预计阅读时间需要3分钟。

如何用二分法查找一个长尾词在有序数组中的位置?

题目:给定一个按照升序排列的长度为n的整数数组以及一个查询q。对于每个查询,返回一个元素k的起始位置和终止位置(位置从0开始计数)。如果数组中不存在该元素,则返回不存在。

题目

给定一个按照升序排列的长度为 $n$ 的整数数组,以及 $q$ 个查询。

对于每个查询,返回一个元素 $k$ 的起始位置和终止位置(位置从 $0$ 开始计数)。

如果数组中不存在该元素,则返回 $-1 -1$。

输入格式 第一行包含整数 $n$ 和 $q$,表示数组长度和询问个数。

第二行包含 $n$ 个整数(均在 $1∼10000$ 范围内),表示完整数组。

如何用二分法查找一个长尾词在有序数组中的位置?

接下来 $q$ 行,每行包含一个整数 $k$,表示一个询问元素。

输出格式 共 $q$ 行,每行包含两个整数,表示所求元素的起始位置和终止位置。

如果数组中不存在该元素,则返回 $-1 -1$。

数据范围 $1≤n≤100000$

$1≤q≤10000$

$1≤k≤10000$ 输入样例:

6 3 1 2 2 3 3 4 3 4 5

输出样例:

3 4 5 5 -1 -1

思路

二分模板

  1. 找左边界

while (l < r) { int mid = (l + r) >> 1; if (k <= f[mid]) r = mid; else l = mid + 1; }

  1. 找右边界

int l = 0, r = n - 1; while (l < r) { int mid = (l + r + 1) >> 1; // +1是为了防止越界 if (k >= f[mid]) l = mid; else r = mid - 1; }

代码

#include <iostream> using namespace std; const int N = 100010; int n, q, k, f[N]; void bs() { int l = 0, r = n - 1; while (l < r) { int mid = (l + r) >> 1; if (k <= f[mid]) r = mid; else l = mid + 1; } if (f[l] != k) cout << "-1 -1" << endl; else { cout << l << " "; int l = 0, r = n - 1; while (l < r) { int mid = (l + r + 1) >> 1; if (k >= f[mid]) l = mid; else r = mid - 1; } cout << l << endl; } } int main() { cin >> n >> q; for (int i = 0; i < n; i ++ ) scanf("%d", &f[i]); while (q -- ) { cin >> k; bs(); } return 0; }

本文共计594个文字,预计阅读时间需要3分钟。

如何用二分法查找一个长尾词在有序数组中的位置?

题目:给定一个按照升序排列的长度为n的整数数组以及一个查询q。对于每个查询,返回一个元素k的起始位置和终止位置(位置从0开始计数)。如果数组中不存在该元素,则返回不存在。

题目

给定一个按照升序排列的长度为 $n$ 的整数数组,以及 $q$ 个查询。

对于每个查询,返回一个元素 $k$ 的起始位置和终止位置(位置从 $0$ 开始计数)。

如果数组中不存在该元素,则返回 $-1 -1$。

输入格式 第一行包含整数 $n$ 和 $q$,表示数组长度和询问个数。

第二行包含 $n$ 个整数(均在 $1∼10000$ 范围内),表示完整数组。

如何用二分法查找一个长尾词在有序数组中的位置?

接下来 $q$ 行,每行包含一个整数 $k$,表示一个询问元素。

输出格式 共 $q$ 行,每行包含两个整数,表示所求元素的起始位置和终止位置。

如果数组中不存在该元素,则返回 $-1 -1$。

数据范围 $1≤n≤100000$

$1≤q≤10000$

$1≤k≤10000$ 输入样例:

6 3 1 2 2 3 3 4 3 4 5

输出样例:

3 4 5 5 -1 -1

思路

二分模板

  1. 找左边界

while (l < r) { int mid = (l + r) >> 1; if (k <= f[mid]) r = mid; else l = mid + 1; }

  1. 找右边界

int l = 0, r = n - 1; while (l < r) { int mid = (l + r + 1) >> 1; // +1是为了防止越界 if (k >= f[mid]) l = mid; else r = mid - 1; }

代码

#include <iostream> using namespace std; const int N = 100010; int n, q, k, f[N]; void bs() { int l = 0, r = n - 1; while (l < r) { int mid = (l + r) >> 1; if (k <= f[mid]) r = mid; else l = mid + 1; } if (f[l] != k) cout << "-1 -1" << endl; else { cout << l << " "; int l = 0, r = n - 1; while (l < r) { int mid = (l + r + 1) >> 1; if (k >= f[mid]) l = mid; else r = mid - 1; } cout << l << endl; } } int main() { cin >> n >> q; for (int i = 0; i < n; i ++ ) scanf("%d", &f[i]); while (q -- ) { cin >> k; bs(); } return 0; }