数的范围(二分模板)

    技术2022-07-10  121

    题目

    给定一个按照升序排列的长度为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

    思路

    俩次二分,第一次二分数的左边,第二次二分数的右边。 俩次的区别在于mid是否+1

    package No1; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.io.PrintWriter; import java.io.StreamTokenizer; public class Main { public static void main(String[] args) throws IOException { StreamTokenizer in = new StreamTokenizer(new BufferedReader( new InputStreamReader(System.in))); PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out)); in.nextToken(); int n = (int) in.nval; in.nextToken(); int m = (int) in.nval; int arr[] = new int[n]; for (int i = 0; i < n; i++) { in.nextToken(); arr[i] = (int) in.nval; } for (int i = 0; i < m; i++) { in.nextToken(); int val = (int) in.nval; int l = 0, r = n - 1; while (l < r) { int mid = (l + r) / 2; if (arr[mid] >= val) r = mid; else l = mid + 1; } if (arr[l] != val) out.println("-1 -1"); else { out.print(l + " "); l = 0; r = n - 1; while (l < r) { int mid = (l + r + 1) / 2; if (arr[mid] <= val) l = mid; else r = mid - 1; } out.println(l); } } out.flush(); } }
    Processed: 0.014, SQL: 9