- A
- B
- C
- D
- E
- F
- G
- H
- I
Дерево поиска
A. Простое двоичное дерево поиска
Ограничение по времени на тест: 2 секунды
Ограничение по памяти на тест: 512 мегабайт
Реализуйте просто двоичное дерево поиска.
Входные данные
Входной файл содержит описание операций с деревом, их количество не превышает 100. В каждой строке находится одна из следующих операций:
insert
$x$ — добавить в дерево ключ $x$. Если ключ $x$ есть в дереве, то ничего делать не надо;delete
$x$ — удалить из дерева ключ $x$. Если ключа $x$ в дереве нет, то ничего делать не надо;exists
$x$ — если ключ $x$ есть в дереве выведите «true
», если нет «false
»;next
$x$ — выведите минимальный элемент в дереве, строго больший $x$, или «none
» если такого нет;prev
$x$ — выведите максимальный элемент в дереве, строго меньший $x$, или «none
» если такого нет.
В дерево помещаются и извлекаются только целые числа, не превышающие по модулю $10^9$.
Выходные данные
Выведите последовательно результат выполнения всех операций exists
, next
, prev
. Следуйте формату выходного файла из примера.
Пример
Входные данные
insert 2
insert 5
insert 3
exists 2
exists 4
next 4
prev 4
delete 5
next 4
prev 4
Выходные данные
true
false
5
3
none
3
Решение
B. Сбалансированное двоичное дерево поиска
Ограничение по времени на тест: 2 секунды
Ограничение по памяти на тест: 512 мегабайт
Реализуйте сбалансированное двоичное дерево поиска.
Входные данные
Входной файл содержит описание операций с деревом, их количество не превышает $10^5$. В каждой строке находится одна из следующих операций:
insert
$x$ — добавить в дерево ключ $x$. Если ключ $x$ есть в дереве, то ничего делать не надо;delete
$x$ — удалить из дерева ключ $x$. Если ключа $x$ в дереве нет, то ничего делать не надо;exists
$x$ — если ключ $x$ есть в дереве выведите «true
», если нет «false
»;next
$x$ — выведите минимальный элемент в дереве, строго больший $x$, или «none
» если такого нет;prev
$x$ — выведите максимальный элемент в дереве, строго меньший $x$, или «none
» если такого нет.
В дерево помещаются и извлекаются только целые числа, не превышающие по модулю $10^9$.
Выходные данные
Выведите последовательно результат выполнения всех операций exists
, next
, prev
. Следуйте формату выходного файла из примера.
Пример
Входные данные
insert 2
insert 5
insert 3
exists 2
exists 4
next 4
prev 4
delete 5
next 4
prev 4
Выходные данные
true
false
5
3
none
3
Решение
C. Добавление ключей
Ограничение по времени на тест: 2 секунды
Ограничение по памяти на тест: 256 мегабайт
Вы работаете в компании Макрохард и вас попросили реализовать структуру данных, которая будет хранить множество целых ключей.
Будем считать, что ключи хранятся в бесконечном массиве $A$, проиндексированном с $1$, исходно все его ячейки пусты. Структура данных должна поддерживать следующую операцию:
Insert
$(L, K)$, где $L$ — позиция в массиве, а $K$ — некоторое положительное целое число.
Операция должна выполняться следующим образом:
- Если ячейка $A[L]$ пуста, присвоить $A[L] \gets K$.
- Если $A[L]$ непуста, выполнить
Insert
$(L+1, A[L])$ и затем присвоить $A[L] \gets K$.
По заданным $N$ целым числам $L_1, L_2, \ldots, L_N$ выведите массив после выполнения последовательности операций:
Insert
$(L_1, 1)$ Insert
$(L_2, 2)$ $\ldots$ Insert
$(L_N, N)$
Входные данные
Первая строка входного файла содержит числа $N$ — количество операций Insert
, которое следует выполнить и $M$ — максимальную позицию, которая используется в операциях Insert
$(1 ⩽ N ⩽ 131\ 072, 1 ⩽ M ⩽ 131\ 072)$.
Следующая строка содержит $N$ целых чисел $L_i$, которые описывают операции Insert
, которые следует выполнить $(1 ⩽ L_i ⩽ M)$.
Выходные данные
Выведите содержимое массива после выполнения всех сделанных операций Insert
. На первой строке выведите $W$ — номер максимальной непустой ячейки в массиве. Затем выведите $W$ целых чисел — $A[1], A[2], \ldots, A[W]$. Выводите нули для пустых ячеек.
Пример
Входные данные
5 4
3 3 4 1 3
Выходные данные
6
4 0 5 2 3 1
Решение
D. И снова сумма
Ограничение по времени на тест: 5 секунд
Ограничение по памяти на тест: 256 мегабайт
Реализуйте структуру данных, которая поддерживает множество $S$ целых чисел, с котором разрешается производить следующие операции:
- $\operatorname{add}(i)$ — добавить в множество $S$ число $i$ (если он там уже есть, то множество не меняется);
- $\operatorname{sum}(l, r)$ — вывести сумму всех элементов $x$ из $S$, которые удовлетворяют неравенству $l ⩽ x ⩽ r$.
Входные данные
Исходно множество $S$ пусто. Первая строка входного файла содержит $n$ — количество операций $(1 ⩽ n ⩽ 300\ 000)$. Следующие $n$ строк содержат операции. Каждая операция имеет вид либо «+ $i$», либо «? $l$ $r$». Операция «? $l$ $r$» задает запрос $\operatorname{sum}(l, r)$.
Если операция «+ $i$» идет во входном файле в начале или после другой операции «+», то она задает операцию $\operatorname{add}(i)$. Если же она идет после запроса «?», и результат этого запроса был $y$, то выполняется операция $\operatorname{add}((i + y) \bmod 10^9)$.
Во всех запросах и операциях добавления параметры лежат в интервале от $0$ до $10^9$.
Выходные данные
Для каждого запроса выведите одно число — ответ на запрос.
Пример
Входные данные
6
+ 1
+ 3
+ 3
? 2 4
+ 1
? 2 4
Выходные данные
3
7
Решение
$K$-й максимум
Ограничение по времени на тест: 2 секунды
Ограничение по памяти на тест: 512 мегабайт
Напишите программу, реализующую структуру данных, позволяющую добавлять и удалять элементы, а также находить $k$-й максимум.
Входные данные
Первая строка входного файла содержит натуральное число $n$ — количество команд $(n ⩽ 100\ 000)$. Последующие $n$ строк содержат по одной команде каждая. Команда записывается в виде двух чисел $c_i$ и $k_i$ — тип и аргумент команды соответственно ($|k_i| ⩽ 10^9$). Поддерживаемые команды:
- 1: Добавить элемент с ключом $k_i$.
- 0: Найти и вывести $k_i$-й максимум.
- -1: Удалить элемент с ключом $k_i$.
Гарантируется, что в процессе работы в структуре не требуется хранить элементы с равными ключами или удалять несуществующие элементы. Также гарантируется, что при запросе $k_i$-го максимума, он существует.
Выходные данные
Для каждой команды нулевого типа в выходной файл должна быть выведена строка, содержащая единственное число — $k_i$-й максимум.
Пример
Входные данные
11
1 5
1 3
1 7
0 1
0 2
0 3
-1 5
1 10
0 1
0 2
0 3
Выходные данные
7
5
3
10
7
3
Решение
F. Неявный ключ
Ограничение по времени на тест: 2 секунды
Ограничение по памяти на тест: 256 мегабайт
Научитесь быстро делать две операции с массивом:
add i x
— добавить после $i$-го элемента $x$ $(0 ⩽ i ⩽ n)$del i
— удалить $i$-й элемент $(1 ⩽ i ⩽ n)$
Входные данные
На первой строке $n_0$ и $m$ $(1 ⩽ n_0, m ⩽ 10^5)$ — длина исходного массива и количество запросов. На второй строке $n_0$ целых чисел от $0$ до $10^9 - 1$ — исходный массив. Далее $m$ строк, содержащие запросы. Гарантируется, что запросы корректны: например, если просят удалить $i$-й элемент, он точно есть.
Выходные данные
Выведите конечное состояние массива. На первой строке количество элементов, на второй строке сам массив.
Пример
Входные данные
3 4
1 2 3
del 3
add 0 9
add 3 8
del 2
Выходные данные
3
9 2 8
Решение
G. Переместить в начало
Ограничение по времени на тест: 6 секунд
Ограничение по памяти на тест: 512 мегабайт
Вам дан массив $a_1 = 1$, $a_2 = 2$, $\ldots$, $a_n = n$ и последовательность операций: переместить элементы с $l_i$ по $r_i$ в начало массива. Например, для массива 2, 3, 6, 1, 5, 4, после операции (2, 4) новый порядок будет 3, 6, 1, 2, 5, 4. А после применения операции (3, 4) порядок элементов в массиве будет 1, 2, 3, 6, 5, 4.
Выведите порядок элементов в массиве после выполнения всех операций.
Входные данные
В первой строке входного файла указаны числа $n$ и $m$ $(2 ⩽ n ⩽ 100\ 000, 1 ⩽ m ⩽ 100\ 000)$ — число элементов в массиве и число операций. Следующие $m$ строк содержат операции в виде двух целых чисел: $l_i$ и $r_i$ $(1 ⩽ l_i ⩽ r_i ⩽ n)$.
Выходные данные
Выведите $n$ целых чисел — порядок элементов в массиве после применения всех операций.
Пример
Входные данные
6 3
2 4
3 5
2 2
Выходные данные
1 4 5 2 3 6
Решение
H. Развороты
Ограничение по времени на тест: 1 секунда
Ограничение по памяти на тест: 512 мегабайт
Вам дан массив $a_1 = 1$, $a_2 = 2$, $\ldots$, $a_n = n$ и последовательность операций: переставить элементы с $l_i$ по $r_i$ в обратном порядке. Например, для массива 1, 2, 3, 4, 5, после операции (2, 4) новый порядок будет 1, 4, 3, 2, 5. А после применения операции (3, 5) порядок элементов в массиве будет 1, 4, 5, 2, 3.
Выведите порядок элементов в массиве после выполнения всех операций.
Входные данные
В первой строке входного файла указаны числа $n$ и $m$ $(2 ⩽ n ⩽ 100\ 000, 1 ⩽ m ⩽ 100\ 000)$ — число элементов в массиве и число операций. Следующие $m$ строк содержат операции в виде двух целых чисел: $l_i$ и $r_i$ $(1 ⩽ l_i ⩽ r_i ⩽ n)$.
Выходные данные
Выведите $n$ целых чисел — порядок элементов в массиве после применения всех операций.
Пример
Входные данные
5 3
2 4
3 5
2 2
Выходные данные
1 4 5 2 3
Решение
I. Эх, дороги
Ограничение по времени на тест: 2 секунды
Ограничение по памяти на тест: 256 мегабайт
В многострадальном Тридесятом государстве опять готовится дорожная реформа. Впрочем, надо признать, дороги в этом государстве находятся в довольно плачевном состоянии. Так что реформа не повредит. Одна проблема — дорожникам не развернуться, поскольку в стране действует жесткий закон — из каждого города должно вести не более двух дорог. Все дороги в государстве двусторонние, то есть по ним разрешено движение в обоих направлениях (разумеется, разметка отсутствует). В результате реформы некоторые дороги будут строиться, а некоторые другие закрываться на бессрочный ремонт.
Петя работает диспетчером в службе грузоперевозок на дальние расстояния. В связи с предстоящими реформами, ему необходимо оперативно определять оптимальные маршруты между городами в условиях постоянно меняющейся дорожной ситуации. В силу большого количества пробок и сотрудников дорожной полиции в городах, критерием оптимальности маршрута считается количество промежуточных городов, которые необходимо проехать.
Помогите Пете по заданной последовательности сообщений об изменении структуры дорог и запросам об оптимальном способе проезда из одного города в другой, оперативно отвечать на запросы.
Входные данные
В первой строке входного файла заданы числа $n$ — количество городов, $m$ — количество дорог в начале реформы и $q$ — количество сообщений об изменении дорожной структуры и запросов $(1 ⩽ n, m ⩽ 100\ 000, q ⩽ 200\ 000)$. Следующие $m$ строк содержат по два целых числа каждая — пары городов, соединенных дорогами перед реформой. Следующие $q$ строк содержат по три элемента, разделенных пробелами. «+ $i$ $j$» означает строительство дороги от города $i$ до города $j$, «- $i$ $j$» означает закрытие дороги от города $i$ до города $j$, «? $i$ $j$» означает запрос об оптимальном пути между городами $i$ и $j$.
Гарантируется, что в начале и после каждого изменения никакие два города не соединены более чем одной дорогой, и из каждого города выходит не более двух дорог. Никакой город не соединяется дорогой сам с собой.
Выходные данные
На каждый запрос вида «? $i$ $j$» выведите одно число — минимальное количество промежуточных городов на маршруте из города $i$ в город $j$. Если проехать из $i$ в $j$ невозможно, выведите -1.
Пример
Входные данные
5 4 6
1 2
2 3
1 3
4 5
? 1 2
? 1 5
- 2 3
? 2 3
+ 2 4
? 1 5
Выходные данные
0
-1
1
2