Разбор
В данной задаче требуется найти число в отсортированном массиве, что можно сделать с помощью бинарного поиска.
Пусть — отсортированный массив длины , состоящий из целых чисел. Функция binary_search возвращает true, если число присутствует в массиве. Входной массив читается за , запросов выполняются за .
Функция lower_bound возвращает указатель на первую позицию, в которую можно вставить элемент без нарушения свойства отсортированности массива.
Функция upper_bound возвращает указатель на последнюю позицию, в которую можно вставить элемент без нарушения свойства отсортированности массива.
Если lower_boundupper_bound, то число присутствует в массиве. В противном случае числа в массиве нет.
Java функция Arrays.binarySearch() возвращает индекс найденного элемента в массиве. Если массив содержит несколько одинаковых ключей, то возвращается индекс любого из них.
Если отсутствует в массиве , то функция Arrays.binarySearch возвращает значение , где — индекс первого элемента, большего . Если больше всех элементов массива , то .
Функция bisect в Python используется для выполнения бинарного поиска в отсортированных последовательностях. Она помогает найти место вставки элемента в отсортированный список, чтобы сохранить порядок сортировки. Это может быть полезно, например, для оптимизации добавления новых элементов в упорядоченный список или для определения, куда вставить элемент в массив, чтобы сохранить сортировку.
bisect предоставляет две основные функции:
bisect.bisect_left. Эта функция находит точку вставки для элемента в отсортированном списке . Если элемент уже присутствует в списке, то bisect_left вернет индекс первого вхождения . Если элемент отсутствует, функция вернет индекс, где можно вставить , не нарушив порядок сортировки.
bisect.bisect_right. Аналогична bisect_left, но возвращает индекс для вставки элемента после существующих вхождений в список .
Обе функции принимают необязательные аргументы и , которые определяют диапазон поиска в списке. По умолчанию , а .
Реализация собственного бинарного поиска. Пусть требуется найти элемент в массиве на промежутке . Делим отрезок пополам, положим . Если , то элемент находится на отрезке . Иначе следует продолжить поиск на отрезке .
Структура данных set. Занесем числа из входного массива в структуру данных . Если некоторое число присутствует в массиве несколько раз, в set оно будет добавлено только один раз. При этом результат запроса на присутствие заданного элемента в массиве не изменится.
Элемент присутствует во множестве (во входном массиве), если .
Элементы входного массива заносятся во множество за , запросов выполняются за .
Реализация алгоритма —
Объявим рабочий массив.
#define MAX 1000000 int m[MAX];
Читаем входные данные.
scanf("%d %d", &n, &q); for (i = 0; i < n; i++) scanf("%d", &m[i]);
Последовательно обрабатываем запросов.
for (i = 0; i < q; i++) {
Читаем число .
scanf("%d", &x);
Число присутствует в массиве , если функция binary_search возвращает true.
if (binary_search(m, m + n, x) == 1) puts("YES"); else puts("NO"); }
Реализация алгоритма — lower_bound, upper_bound
Объявим рабочий массив.
#define MAX 1000000 int m[MAX];
Читаем входные данные.
scanf("%d %d", &n, &q); for (i = 0; i < n; i++) scanf("%d", &m[i]);
Последовательно обрабатываем запросов.
for (i = 0; i < q; i++) {
Читаем число .
scanf("%d", &x);
Число присутствует в массиве , если lower_boundupper_bound
if (lower_bound(m, m + n, x) != upper_bound(m, m + n, x)) puts("YES"); else puts("NO"); }
Реализация алгоритма — собственный бинарный поиск
Объявим рабочий массив.
#define MAX 1000000 int m[MAX];
Функция my_bin_search реализует бинарный поиск и возвращает , если число присутствует в массиве в диапазоне .
int my_bin_search(int *m, int start, int end, int x) {
Запускаем бинарный поиск на интервале .
while (start < end) { int mid = (start + end) / 2; if (x > m[mid]) start = mid + 1; else end = mid; }
Возвращаем результат.
return m[start] == x; }
Основная часть программы. Читаем входные данные.
scanf("%d %d", &n, &q); for (i = 0; i < n; i++) scanf("%d", &m[i]);
Последовательно обрабатываем запросов.
for (i = 0; i < q; i++) {
Читаем число .
scanf("%d", &x);
Число присутствует в массиве , если my_bin_search возвращает .
if (my_bin_search(m, 0, n - 1, x)) puts("YES"); else puts("NO"); }
Реализация алгоритма — set,
#include <cstdio> #include <algorithm> #include <set> using namespace std; int i, n, q, x; set<int> s; int main(void) { scanf("%d %d", &n, &q); for (i = 0; i < n; i++) { scanf("%d", &x); s.insert(x); } for (i = 0; i < q; i++) { scanf("%d", &x); if (s.find(x) != s.end()) puts("YES"); else puts("NO"); } return 0; }
Java реализация — собственный бинарный поиск
import java.util.*; import java.io.*; public class Main { static int my_bin_search(int m[], int start, int end, int x) { while (start < end) { int mid = (start + end) / 2; if (x > m[mid]) start = mid + 1; else end = mid; } return (m[start] == x) ? 1 : 0; } public static void main(String[] args) { FastScanner con = new FastScanner(new InputStreamReader(System.in)); int n = con.nextInt(); int q = con.nextInt(); int m[] = new int[n]; for(int i = 0; i < n; i++) m[i] = con.nextInt(); for(int i = 0; i < q; i++) { int x = con.nextInt(); if(my_bin_search(m,0,n-1,x) == 1) System.out.println("YES"); else System.out.println("NO"); } } } class FastScanner { private BufferedReader br; private StringTokenizer st; public FastScanner(InputStreamReader reader) { br = new BufferedReader(reader); } public String next() { while (st == null || !st.hasMoreTokens()) { try { st = new StringTokenizer(br.readLine()); } catch (Exception e) { e.printStackTrace(); } } return st.nextToken(); } public int nextInt() { return Integer.parseInt(next()); } public double nextDouble() { return Double.parseDouble(next()); } public void close() throws Exception { br.close(); } }
Java реализация — Arrays.binarySearch
import java.util.*; import java.io.*; public class Main { public static void main(String[] args) { FastScanner con = new FastScanner(new InputStreamReader(System.in)); int n = con.nextInt(); int q = con.nextInt(); int m[] = new int[n]; for(int i = 0; i < n; i++) m[i] = con.nextInt(); for(int i = 0; i < q; i++) { int x = con.nextInt(); if(Arrays.binarySearch(m, x) >= 0) System.out.println("YES"); else System.out.println("NO"); } } } class FastScanner { private BufferedReader br; private StringTokenizer st; public FastScanner(InputStreamReader reader) { br = new BufferedReader(reader); } public String next() { while (st == null || !st.hasMoreTokens()) { try { st = new StringTokenizer(br.readLine()); } catch (Exception e) { e.printStackTrace(); } } return st.nextToken(); } public int nextInt() { return Integer.parseInt(next()); } public double nextDouble() { return Double.parseDouble(next()); } public void close() throws Exception { br.close(); } }
Python реализация
Импортируем модуль bisect.
import bisect
Читаем входные данные.
n, q = map(int,input().split()) lst = list(map(int,input().split()))
Последовательно обрабатываем запросов.
for _ in range(q):
Читаем число .
x = int(input())
Число присутствует в массиве , если bisect_leftbisect_right
if bisect.bisect_left(lst, x) != bisect.bisect_right(lst, x): print("YES") else: print("NO")
Python реализация — собственный бинарный поиск
Функция my_bin_search реализует бинарный поиск:
если число отсутствует в списке , то функция возвращает .
иначе возвращается позиция числа в списке .
def my_bin_search(a, x): start = 0 end = len(a) – 1
Запускаем бинарный поиск на интервале .
while start < end: mid = (start + end) // 2; if x > a[mid]: start = mid + 1; else: end = mid;
Возвращаем результат.
if a[start] == x: return start else: return -1;
Основная часть программы. Читаем входные данные.
n, q = map(int,input().split()) lst = list(map(int,input().split()))
Последовательно обрабатываем запросов.
for _ in range(q):
Читаем число .
x = int(input())
Запускаем бинарный поиск. Выводим соответствующий ответ.
if my_bin_search(lst,x) != -1: print("YES") else: print("NO")