- Районна олімпіада 2020 (розбір)
- Шкільна олімпіада 2020 (розбір)
- Обласна олімпіада 2020 (розбір)
- Обласна олімпіада 2019 (розбір)
- Районна олімпіада 2019 (розбір)
- Районна олімпіада 2018 (розбір)
- Обласна олімпіада 2021 - Тур 1 (розбір)
- Обласна олімпіада 2021 - Тур 2 (розбір)
- Шкільна олімпіада 2018 (розбір)
- Шкільна олімпіада 2019 (розбір)
- Обласна олімпіада 2018 (розбір)
- Обласна олімпіада 2021 - Фінал (розбір)
- Шкільна олімпіада 2017 (розбір)
- Районна олімпіада 2017 (розбір)
- Обласна олімпіада 2017 (розбір)
- Обласна олімпіада 2016 (розбір)
- Районна олімпіада 2015 (розбір)
- Районна олімпіада 2021 (розбір)
- Районна олімпіада 2014 (розбір)
- Районна олімпіада 2013 (розбір)
- Обласна олімпіада 2015 (розбір)
- Обласна олімпіада 2022 (розбір)
- NextGen Contest 1(розбір)
- Шкільна олімпіада 2022 (розбір)
- Районна олімпіада 2022 (розбір)
- Обласна iнтернет олiмпiада 2023 - Тур 1 (розбір)
- Обласна iнтернет олiмпiада 2023 - Тур 2 (розбір)
- Обласна олiмпiада 2023 (розбір)
- Короткий розбір The Algo Battles 2023 - Етап 1
- Короткий розбір The Algo Battles 2023 - Етап 2
- Короткий розбір The Algo Battles 2023 - Етап 3
- Короткий розбір The Algo Battles 2023 - Етап 4
- Короткий розбір Lucky Numbers Contest 2023
- Короткий розбір The Algo Battles 2023 - Етап 5
- ОТГ олімпіада 2023 (розбір)
- Короткий розбір The Algo Battles 2023 - Етап 6
- Районна олімпіада 2023 (розбір)
- Короткий розбір The Algo Battles 2023 - Етап 7
- Обласна олімпіада 2024 (розбір)
- Короткий розбір The Algo Battles 2024 - Етап 1
- Короткий розбір The Algo Battles 2024 - Етап 2
- Короткий розбір The Algo Battles 2024 - Етап 3
- Розбір 4 дня літньої школи в Хусті 2024
- Розбір 3 дня літньої школи в Хусті 2024
- Короткий розбір The Algo Battles 2024 - Етап 4
- Розбір до першого етапу Першості України з програмування 2024
- Розбір до другого етапу Першості України з програмування 2024
- ОТГ олімпіада 2024 (розбір)
Порахуємо, скільки разів Марічка може виграти каменем. Ця кількість не може бути більша за кількість ігор, у яких Марічка поставила камінь, і не може бути більша за кількість ігор, у яких Зеник поставив ножиці, тобто \(min(r_M, s_Z)\). Аналогічно, кількість ігор, у яких Марічка може перемогти ножицями й папером рівна \(min(s_M, p_Z)\) i \(min(p_M, r_Z)\), відповідно. Відповідь до задачі буде рівна сумі цих трьох доданків.
Нехай кількість одиниць рівна \(a\), а кількість нулів рівна \(b\). Якщо \(a \le b\) тоді \(2 \cdot a \le a + b = n\). Тому одиниць є не більше ніж половина, і якщо ми видалимо їх усіх, то отримаємо рядок з нулів, який є паліндромом. Аналогічно, коли \(b \le a\), ми можемо видалити всі нулі й отримати рядок з одиниць, який також є паліндромом.
Можна зауважити, що оптимальний рядок — це конкатенація рядків виду
bohdan
, danylo
, maksym
та
bohdanylo
. Без обмеження загальності, уважатимемо, що \(d \le b\), а отже немає сенсу
використовувати рядок danylo
в нашій назві (якщо він не є
частиною рядка bohdanylo
).
Розглянемо два варіанти:
Не використовувати рядок
maksym
у назві. Припустимо, що в оптимальній назві рядокbohdan
зустрічається принаймні 9 разів, аbohdanylo
— принаймні 6 разів. Тоді при заміні дев’яти рядківbohdan
на шість рядківbohdanylo
(або навпаки) прибуток не зменшиться, а отже існує оптимальна назва, де кількість рядківbohdan
менша ніж 9, або кількість рядківbohdanylo
менша ніж 6. Тому переберемо кількість рядківbohdan
від 0 до 8, а рeшту вільного місця виділимо під рядокbohdanylo
(та навпаки). У такий спосіб ми отримаємо оптимальну назву для команди.Використаємо рядок
maksym
принаймні один раз. Тоді легко бачити, що рядкиmaksym
ітимуть поряд, і для \(1 \le k\) рядківmaksym
потрібно рівно \(5k + 1\) символів. Аналогічно до попереднього пункту, можна показати, що існує оптимальна назва, у якій або кількість рядківmaksym
, абоbohdan
, абоbohdanylo
не перевищує, наприклад, 20 (існують і строгіші оцінки). Тому перебравши кількість рядків одного із цих типів, зведемо отриману задачу до попереднього пункту (див. код для кращого розуміння).
Складність розв’язку: \(O(1)\) часу та пам’яті.
Розв’язок зі складністю \(O(nmk)\). Переберемо всі можливі \(a\) і \(b\) та перевіримо, чи точки, що з’єднані між собою, належать різним прямокутникам.
Розв’язок зі складністю \(O(n(m^2+k))\). Переберемо \(a\). Якщо для деяких з’єднаних точок \((x_1, y_1), (x_2, y_2)\) виконується \(\left \lfloor{\frac{x_1}{a}}\right \rfloor \ne \left \lfloor{\frac{x_2}{a}}\right \rfloor\), то ці точки будуть у різних прямокутниках. Тепер розглядаємо лише ті пари точок, для яких ця умова не виконується. Треба задовольнити умову \(\left \lfloor{\frac{y_1}{b}}\right \rfloor \ne \left \lfloor{\frac{y_2}{b}}\right \rfloor\).
Тепер маємо одновимірну задачу. Для її розв’язання заведемо масив \(d\). Значення \(d[i]\) означає найменшу \(y\)-координату, не меншу за \(i\), серед усіх точок, що з’єднані з якоюсь точкою з \(y\)-координатою рівною \(i\). Іншими словами, це координата найближчої зверху точки, з’єднаної з точкою з \(y\)-координатою рівною \(i\). Після обчислення такого масиву можемо перебрати \(b\) та перевірити, чи виконується умова \(\left \lfloor{\frac{i}{b}}\right \rfloor \ne \left \lfloor{\frac{d[i]}{b}}\right \rfloor\) для всіх \(i\).
Потрібно перевірити для всіх \(i\) умову \(x_{i+1}-x_i \ge 2\).
Один з варіантів, що дає максимальну кількість будинків з хворими — це коли початкові \(k\) будинків з хворими знаходяться поруч на одній діагоналі. Тоді відповідь буде рівна \(k^2\), але кількість будинків з хворими не може бути більшою за кількість будинків у місті. Отже, відповідь — min(\(k^2\), \(n^2\)).
Зеник може в кожному магазині купувати одноразову маску. У цьому разі він заплатить \(\sum_{i=1}^n a_i\). Цей дивний запис означає суму \(a_i\) за всіма \(i\) від 1 до \(n\).
Якщо ж він вирішить придбати багаторазову маску в \(j\)-ому магазині, то йому доведеться купити одноразові маски в усіх магазинах перед \(j\)-им. Тоді він витратить \(b_j + \sum_{i=1}^{j-1} a_i\). Можна перебрати \(j\) — індекс магазину, де найвигідніше придбати багаторазову маску. Для цього будемо йти індексом \(j\) від 1 до \(n\) і підтримувати значення суми \(a_i\) на префіксі.
Відповіддю буде найменший серед усіх цих варіантів.
Розглянемо граф, вершинами якого будуть люди, причому деякі пари з них будуть з’єднані ребрами, що означатиме дружбу між відповідними людьми.
Запустимо пошук у глибину (або в ширину) з кожної вершини, відповідна людина якої була хворою у початковий момент часу, та помічатимемо відвідані вершини. Важливо не відвідувати вершину 1, а також раніше оброблені вершини. Наприкінці множина помічених сусідів вершини 1 буде відповідати множині друзів, з якими варто обірвати всякі контакти на час пандемії (адже ці друзі можуть стати зараженими).
Складність такого розв’язку — лінійна відносно розміру вхідних даних.
У цій задачу потрібно лише зчитати числа \(a, b, k\) та вивести \(a+b \cdot k\).
Якщо в кожному рядку буде хоча б один заражений квартал, або в
кожному стовпці буде хоча б один заражений квартал, тоді відповідь —
YES
, оскільки ці віруси можуть кожен вибрати свій рядок або
стовпець і в результаті заразити все поле. У протилежному разі —
відповідь NO
, оскільки буде хоча б одна клітинка, у якої в
рядку та стовпці немає жодної зараженої клітинки, і тому вона ніколи не
стане зараженою.
Із заданої множини чисел розміром \(n\) необхідно вибрати \(k\) чисел так, щоб їх сума була непарною.
Поділимо усі числа на дві множини: парні і непарні. Для того щоб сума вибраних чисел була непарною, необхідно вибрати непарну кількість непарних чисел. Далі задачу можна розв’язувати багатьма способами. Один з можливих розв’язків наступний: візьмемо одне непарне число. Тоді, поки ще треба брати числа, і є хоча б два непарних числа, будемо брати по два непарних числа. Якщо після цього необхідно добрати ще чисел, добираємо парні. Якщо ми таким процесом вибрали рівно \(k\) чисел, то вони і є відповіддю на задачу. Інакше, відповіді не існує.
У цій задачі потрібно об’єднати всі задані проміжки \([l_i, r_i]\) та вивести суму \(k\) перших значень, які належать їм.
Застосуємо метод скануючої прямої. Створимо вектор подій \(t\) — відкриття проміжку та закриття. Відкриття відбудеться в момент часу \(l_i\), а закриття — в момент \(r_i+1\) (тобто права границя береться невключно). Причому для кожної події запам’ятаємо її тип — відкриття або закриття. Посортувавши ці події за зростанням, будемо перебирати від першої до останньої та підтримувати баланс відкритих проміжків (поточна кількість подій відкривання мінус кількість подій закривання). Якщо до події \(t_i\) баланс є додатним, це означає, що таблетки з проміжку \([t_i, t_{i+1})\) лікують вірус.
Якщо \(k\) перевищує значення \(t_{i+1}-t_i\) (кількість таблеток у проміжку), потрібно додати суму всіх цих таблеток до відповіді, а від \(k\) відняти їх кількість. У протилежному разі, потрібно лише додати суму перших \(k\) та завершити роботу.
Необхідно заданий рядок довжини \(n\) трансформувати в інший, використовуючи операцію «перенести якийсь символ в кінець рядка». Дозволено використовувати не більше ніж \(n\) операцій. Зрозуміло, що для існування відповіді необхідно, щоб кількості відповідних букв в обох рядках співпадали.
Нехай початковий рядок \(s = s_0s_1...s_{n-1}\), та кінцевий рядок \(t = t_0t_1...t_{n-1}\). Будемо будувати рядок \(t\) зліва направо: першою операцією візьмемо символ \(t_0\), другою операцією — символ \(t_1\) і т. д. Останньою операцією візьмемо останній символ \(t_{n-1}\).
На \(i\)-ому кроці в нас є побудований префікс рядка \(t\) довжини \(i-1\), та використані деякі символи рядка \(s\). Треба серед того, що залишилося в рядку \(s\), знайти символ, який відповідає символу \(t_i\), і застосувати операцію до нього. Найпростіша реалізація такого розв’язку працює за час \(O(n^2)\) та набирає 15 балів з 25 можливих.
Оптимізувати цей розв’язок можна так: для кожної з 26 букв запишемо позиції їх входження в рядок \(s\). Кожен символ будемо використовувати справа наліво. Коли беремо якийсь символ, все що треба зробити — пройтися по всіх вказівниках для інших символів і для тих, що є праворуч, запам’ятати, що вони тепер змістилися на одну позицію ліворуч. Така оптимізація перетворює розв’язок у лінійний, тобто \(O(n)\).
У цій задачі дві точки рухаються, кожна в деякому напрямку і з деякою швидкістю. У нас є точка, яка рухається в будь-якому напрямку, зі швидкістю, яка не перевищує задану. Треба нашою точкою зловити дві інші.
Оскільки за умовою задачі наша швидкість перевищує швидкість інших двох точок, то ми завжди можемо зловити ці дві точки. Можна показати, що завжди буде вигідною така стратегія: спершу ловимо якомога швидше якусь одну точку. Тоді ловимо іншу. Для розв’язку переберемо два варіанти, яку з точок ловити першою.
Тепер задача зводиться до такої: задано нашу початкову точку (\(x\), \(y\)), нашу максимальну швидкість \(v\), початкове розміщення точки, яку ми хочемо зловити (\(x_0\), \(y_0\)), та вектор руху цієї точки (\(dx\), \(dy\)). Оскільки ми хочемо зловити точку якомога скоріше, то ми будемо рухатися з максимальною швидкістю до точки, у якій ми зустрінемося із ціллю. Нехай це займе час \(t\). Тоді зустріч відбудеться в точці (\(x_0 + dx \cdot t\), \(y_0 + dy \cdot t\)). Умова коректності такої точки є те, що час, за який ми доберемося до неї повинен бути рівно \(t\):
\(t = \frac{\sqrt{(x_0 + dx \cdot t - x)^2 + (y_0 + dy \cdot t - y)^2}}{v}\)
Якщо переписати цю умову, отримаємо квадратне рівняння:
\(t^2 \cdot (v^2 - dx^2 - dy^2) - 2 \cdot t \cdot (dx \cdot (x_0 - x) + dy \cdot (y_0 - y)) - (x_0 - x)^2 - (y_0 - y)^2 = 0\)
Додатний розв’язок цього рівняння — час, за який ми зловимо точку.
Застосуємо метод динамічного програмування. Підвісимо дерево за довільну вершину-корінь та введемо такий стан динаміки: \([v][mask]\) — скількома способами можна розрізати ребра в піддереві вершини \(v\) так, аби утворені компоненти (усі, окрім тої, яка вище за \(v\)) покривали розміри з масиву \(a\), які вибрані в масці \(mask\).
Для обчислення відповіді для вершини \(v\) та всіх масок (їх буде \(2^k\)) потрібно ввести допоміжну динаміку по всіх синах вершини \(v\). Кожен із синів повинен покривати якусь підмаску, а їх об’єднання має утворити цілу маску. Таку динаміку можна перерахувати за \(3^k\) для кожного сина, перебираючи підмаски поточної маски, яку має покривати поточний син.
Після обчислення допоміжної динаміки для синів є дві опції щодо вершини \(v\) — або залишити ребро, яке веде до її батька, або видалити його. При цьому для маски, яку покрили сини, можна визначити, яким буде розмір нової утворено компоненти у випадку, коли ребро буде видаленим. Цей розмір повинен бути присутнім серед усіх непокритих значень у масці. Якщо їх декілька, переберемо кожен варіант вибору та виставимо відповідний біт в 1.
У результаті в стані \([root][2^k-1]\) буде записано відповідь. Проте деякі розрізання могли бути пораховані декілька разів. Це відбуватиметься у разі, коли в масиві \(a\) були однакові значення. Причому якщо якесь значення повторювалось \(c\) разів, то відповідь була домножена на \(c!\), оскільки кожен з варіант був обраний рівно один раз. Тому наприкінці для кожного значення масиву \(a\) поділимо відповідь на \(c!\), де \(c\) — кількість входжень цього значення в масив \(a\).
У задачі необхідно вивести 47-ий день заданого року. Таким днем
кожного року є 16 лютого. Відповідно для розв’язку задачі достатньо
просто вивести рядок 16.02.
і потім номер року, який треба
зчитати з вводу.
За умовою задачі потрібно згенерувати перестановку \(n\) чисел так, щоб в ній було рівно \(k\) локальних мінімумів (чисел, сусіди якого більші за саме число), або сказати, що цього зробити не можна.
Зрозуміло, що неможливо зробити більше ніж \(\frac{n-1}{2}\) локальних мінімумів. Тому у
випадках, коли \(k >
\frac{n-1}{2}\), виведемо -1
.
Щоб створити локальний мінімум у перестановці, нам достатньо просто поміняти місцями два сусідні числа у зростаючій послідовності. Щоб створити \(k\) локальних мінімумів просто зробимо \(k\) таких операцій. Наприклад:
\(1 2 3 4 5 6 7 \rightarrow 1 \Leftrightarrow 2 3 \Leftrightarrow 4 5 \Leftrightarrow 6 7 \rightarrow 2 1 4 3 6 5 7\)
Очевидно, що аби з рядка \(s\) можна було утворити \(t\), потрібно аби \(t\) був підпослідовністю \(s\). Для того щоб це перевірити, достатньо пройти циклом по рядку \(t\), підтримуючи вказівник на відповідне входження такого ж символу в \(s\). При переході до наступного символу в \(t\) потрібно сунути вказівник \(s\), допоки не знайдеться відповідний символ. Якщо вказівник прийшов у кінець рядка, і шуканий символ не був знайдений — підпослідовності не існує.
Після того як відомо, чи можна із \(s\) утворити \(t\), потрібно визначити мінімальну кількість кроків, необхідну для цього. Єдиним обмеженням є той факт, що не можна видаляти більше ніж два однакові символи в межах одного кроку. З цього випливає, що цю кількість можна окремо порахувати для кожної букви, а потім знайти максимальне значення. Зрозуміло, що якщо певну букву потрібно видалити \(x\) разів, то кількість кроків для цього — це \(\lceil \frac{x}{2} \rceil\) (заокруглене вгору).
У задачі задано послідовність із 4 і 7. За одну операцію можна видалити якийсь елемент з послідовності й додати до рахунку суму лівого й правого сусідів. Треба видалити всі елементи, крім першого й останнього, максимізувавши рахунок.
Задача розв’язується жадібно. Спочатку будемо видаляти четвірки, які є сусідами з хоча б однією сімкою, поки не видалимо всі четвірки (це завжди можна зробити за умови якщо присутня хоча б одна сімка). Потім видалимо всі сімки в такому порядку, щоб кожна сімка, яку ми видаляємо, сусідила з двома іншими сімками. Коректність такого підходу легко бачити, якщо розглянути еквівалентну задачу, у якій замість \(4\) і \(7\) є \(0\) і \(1\).
Реалізувати такий алгоритм можна, використовуючи структуру даних стек. Проходимося по послідовності зліва направо й кладемо елементи на стек. Якщо пробуємо поставити \(7\) на \(4\), то видаляємо \(4\). Якщо ставимо \(4\) на \(7\), то видаляємо \(4\) (не ставимо на стек). У результаті залишиться послідовність із сімок, яку треба опрацювати окремо.
За умовою задачі потрібно вивести координати центру кола певного радіусу, яке падає з точки \((x,\infty)\) після того, як воно торкнеться прямої \(y=0\) або іншого кола. Якщо коло не дотикається до інших, то відповідь для нього — \((x, r)\). Якщо ж дотикається — потрібно знайти найвищу точку \((x,y)\), де відбувається дотик. Для цього просто переберемо всі кола, що вже зупинилися, і спробуємо знайти точку, у якій ми будемо до такого кола дотикатися.
Знайти таку точку дуже просто. У момент дотику відстань між центрами двох кіл рівна сумі їхніх радіусів. Координати \(x\) центрів кожного з кіл нам відомі спочатку. За теоремою Піфагора можемо визначити, що \((y-y_i)^2 = (r + r_i)^2 - (x - x_i)^2\). Найбільше значення \(y\) і буде шуканою координатою \(y\) центра кола, що падає. Варто також звернути увагу на те, що для того, щоб коло зупинилося, відстань між центрами кіл має бути строго меншою за суму їхніх радіусів.
У задачі задано граф, у якому деякі ребра мають вагу, а деякі — ні. Необхідно зважити всі ребра, щоб найкоротша відстань між першою і останньою вершинами була рівна заданому числу \(w\).
У першій підзадачі, яка вартувала 10 балів, усі ребра початково не мали ваги. Для того щоб розв’язати цю підзадачу, достатньо знайти шлях між першою і останньою вершинами, на якому є найменша кількість ребер, наприклад, алгоритмом пошуку вшир (BFS). Нехай ця кількість рівна \(k\). Тоді якщо \(k > w\), то відповіді не існує. Інакше вона завжди існує і її можна досягнути, наприклад, так: всім ребрам не на найкоротшому шляху дамо вагу \(w\), усім ребрам, окрім одного на шляху, дамо 1, а останньому дамо \(w - k\). У такий спосіб будь-який шлях, окрім найкоротшого, буде мати вагу не меншу за \(w\), а найкоротший буде мати вагу рівно \(w\).
Для того щоб розв’язати задачу повністю, спершу зробимо, щоб усі ребра без ваги мали вагу 1. Знайдемо найкоротшу відстань між першою і останньою вершинами, наприклад, алгоритмом Дейкстри. Якщо вона перевищує \(w\), то відповіді не існує.
Тепер будемо перебирати всі ребра, які треба зважити, в довільному порядку і для кожного з них повторимо такий процес. Знайдемо найкоротшу відстань між першою і останньою вершиною. Нехай ця відстань рівна \(d\). Додамо до ваги поточного ребра значення \(w - d\) (це значення завжди буде невід’ємне).
Після того як опрацюємо всі ребра, ще раз знайдемо найкоротшу відстань між першою і останньою вершинами. Якщо вона рівна \(w\), то ми знайшли відповідь. Інакше, відповіді не існує.
Неважко побачити, що задача зводиться до такої — знайти максимальну кількість точок, які можна вибрати на лінії так, аби виконувалися такі умови.
Для кожної компанії був хоча б один варіант вибору кінцевої точки, який би не проходив через жодну з вибраних.
Між кожною парою сусідніх вибраних точок має бути хоча б одна компанія.
Це зведення означає, що ми виділяємо максимальну кількість точок-розділювачів, через які не можуть проходити ремонтні роботи, в той час як між ними має бути хоча б одна. Зрозуміло, що максимізація цього числа є еквівалентною максимізації кількості проміжків, яку просять в умові.
Таку зведену задачу легко розв’язати методом динамічного програмування. Введемо стан — координата останньої вибраної точки — і для цього стану будемо максимізовувати загальну кількість уже вибраних точок. Для переходу з такого стану переберемо наступну вибрану точку справа від поточної. Залишається лише перевірити, чи коректним є такий перехід, а саме, чи існує хоча б одна компанія між цими точками, а також, чи кожна з них «поміститься» між цими точками.
Задано масив цілих чисел. Треба сказати, скільки є таких індексів \(i\), що \(a_i\) та \(a_{i+1}\) різної парності.
Задано натуральне число \(n\). Треба сказати кількість натуральних чисел, що не перевищують \(n\), таких, що їхня сума цифр — щаслива.
Переберемо всі числа від 1 до \(n\) і перевіримо, чи сума цифр щаслива.
Задано масив чисел. Можна видалити деякі з них так, щоб сума чисел, які залишаться, була не меншою за \(x\) і середнє арифметичне цих чисел було максимальне.
Ми хочем, щоб \(\frac{sum}{count}\) чисел, які залишаться, було максимальним. Припустимо, що в нас фіксований \(count\), тоді ми хочем максимізувати суму. Тоді нам достатньо видалити \(n-count\) найменших чисел, щоб максимізувати суму.
Оптимальним рішенням задачі буде видаляти найменше число, поки це можливо.
Марічка й Зеник грають у гру. Є \(n\) купок каменів. Марічка ходить першою і може вибрати підмножину купок розміру від 1 до \(n-1\) і забрати будь-яку ненульову кількість каменів з кожної із цих купок. Зеник має право забирати будь-яку ненульову кількість каменів тільки з однієї купки. Програє той хто не зможе зробити ходу. Хто виграє при оптимальній грі обох?
Припустим, \(n \ge 3\). Марічка може забрати 1 купку першим ходом. Незалежно від ходу Зеника на наступному ході Марічки буде щонайменше \(n-2\) купки і не більше ніж \(n-1\) купка, тому Марічка зможе забрати їх усіх. Якщо \(n = 2\), то Зеник виграє тоді й тільки тоді, коли \(a_0 = a_1\). Він зможе завжди повторювати хід Марічки, але в протилежну купку. Інакше виграє Марічка, звівши гру першим ходом до гри, де \(a_0 = a_1\)
У вас є число \(n < 10^9\). Ви можете поділити (якщо ділиться) його на 4 або відняти 7. Треба сказати, чи можна отримати 1.
Розглянемо задачу з іншого боку — ми можем помножити число на 4 й додати 7. Переберем кількість множень на 4. Їх буде не більше ніж \(\log_4 n\). Нехай кількість множень — \(x\). Наше число — це \(4^x\) і тепер ми можемо додати \(7 \cdot 4^y\), де \(y \le x\). Будем додавати числа жадібно — знаходити таке найбільше \(y\), що \(7 \cdot 4^y\) в сумі з нашим поточним числом менше або рівне тому числу, яке нам потрібне.
Вам задано натуральне число \(n\), та потрібно сказати яку максимальну кількість елементів можна вибрати з множини \(\{1, 2, \ldots, n\}\), так щоб жодні два вибрані елементи не відрізнялись на 4 або 7.
Спершу наведемо приклад розв’язку динамічним програмуванням. Позначимо через \(dp[i][mask]\) найбільшу кількість елементів, які ми можемо вибрати з множини \(\{1, 2, ..., i\}\), причому маска \(mask\) відповідає за те, чи брали ми 7 останніх елементів. З кожного стану є не більше ніж два переходи: ми можемо або взяти поточний елемент (якщо він не конфліктуватиме із жодним з попередніх), або ж пропустити його.
Складність такого алгоритму: \(O(n \cdot 2^7)\) по часу та пам’яті, що проходитиме 80% тестів, втім його можна оптимізувати до \(O(n)\) по пам’яті, тримаючи динаміку пошарово, хоч це й доволі складно реалізовувати.
Другий розв’язок конструктивний. Розглянемо групу з 11 елементів, що йдуть підряд. Можна показати (або на папері, або програмно згенерувати попереднім розв’язком), що з них не можна вибрати більше ніж 5 елементів, що не конфліктуватимуть між собою. Причому саме 5 елементів можна вибрати, наприклад, узявши набори \(\{1, 3, 4, 6, 9\}\) чи \(\{1, 2, 4, 7, 10\}\). Тепер будуватимемо відповідь так: розіб’ємо множинну \(\{1, 2, \ldots, n\}\) на блоки по 11 чисел у кожному (можливо, менше в останньому). Ясно, що з кожного блоку ми можемо взяти не більше ніж 5 чисел. Розглянувши кілька простих випадків, бачимо, що якщо остача \(n\) за модулем 11 рівна 2, то можна в кожній групі вибирати елементи з множини остач \(\{1, 2, 4, 7, 10\}\), а в інших випадках — з множини \(\{1, 3, 4, 6, 9\}\). Формальне доведення залишаємо вам на домашнє завдання :)
Складність такого розв’язку: \(O(n)\) по часу та \(O(1)\) по пам’яті.
Вам задано \(n\) ламп, кожна початково може бути або вимкненою, або ввімкненою. Вам потрібно зробити рівно \(n\) ходів, на \(i\)-ому з них ви вибираєте рівно \(i\) ламп та змінюєте їхній стан на протилежний. Чи можна вимкнути всі лампи?
Як і в попередній задачі, опишемо два розв’язки — конструктивний та за допомогою динамічного програмування.
Спершу розв’язок динамічним програмуванням. Нехай \(dp[i][j]\) — це кількість ламп, які треба було вимкнути на \(і\)-ому кроці, щоб після нього рівно \(j\) ламп були ввімкнені. Зауважимо, що таких можливих кількостей може бути декілька. У такому разі \(dp[i][j]\) — будь-яка з них. Якщо ж після \(i\)-ого кроку взагалі неможливо мати рівно \(j\) ввімкнених ламп, то в \(dp[i][j]\) триматимемо відповідну мітку (наприклад, -1).
Якщо після \(i\)-ого кроку в нас
рівно \(j\) увімкнених ламп і на \((i + 1)\)-ому кроці ми вимикаємо \(k\) ламп, то вмикаємо \((i + 1 - k)\) ламп. Тоді кількість
ввімкнених ламп стане \((j - k + i + 1 -
k)\). Тобто, якщо в стан \(dp[i][j]\) можливо перейти, то можна
оновити \(dp[i + 1][j - k + i + 1 -
k]\) значенням \(k\). Якщо в
стан \(dp[n][0]\) неможливо прийти, то
відповідь — No
. Інакше — Yes
. Для кожного
стану ми знаємо, скільки ламп треба було вимкнути на попередньому кроці,
і можемо симулювати процес. Складність: \(O(n^3)\) часу та \(O(n^2)\) пам’яті.
Конструктивний розв’язок. Покажемо, що з початкового стану ми завжди можемо перейти в стан, де всі (крім, можливо, однієї) лампи є вимкнутими. Спочатку зауважимо, що порядок ходів не має значення, тому робитимемо спочатку \(n\) перемикань, потім \(n - 1\) і так далі. Підтримуватимемо такий інваріант: після ходу з \(і\) перемиканнями є не більше за \(i\) ввімкнених ламп. Спочатку таке, звісно ж, виконується. На кожному кроці будемо в першу чергу вимикати всі ввімкненні лампи, а в другу — вмикати вимкнуті. Якщо на якомусь кроці ми маємо змінити стан \(i\) ламп, причому на його початку було не більше ніж \(i + 1\) ввімкнута лампа, то таким процесом ми залишимо не більше за \(і\) ввімкнутих ламп.
Тепер покажемо, що з ніякого стану ми не можемо перейти якимись ходами в стан, де всі лампи вимкнуті, а якимись іншими — де всі, крім рівно однієї, вимкнуті. Це зрозуміло з міркувань парності, адже парності кількостей перемикань всіх ламп у цих двох кінцевих станах відрізняються, що неможливо з огляду на те, що сума перемикань для досягнення кожного з них є однаковою, а саме \(1 + 2 + \ldots + n = \frac{n \cdot (n + 1)}{2}\), де \(n\) — початкова кількість ламп.
Тому ми виконуватимемо процес, описаний у першій частині, і якщо в кінцевому стані всі лампи вимкнені, то це і є розв’язок, інакше — розв’язку не існує.
Складність такого розв’язку: \(O(n^2)\) часу та пам’яті.
Задано два цілі числа. Треба вивести третє, таке що одне з двох чисел не вході є меншим за третє, а інше — більше.
Якщо \(|a-b| \le 1\), то таке зробити неможливо. Інакше відповідь існує. Наприклад, завжди підходить число \(min\{a, b\} + 1\).
Задано рядок символів. Потрібно сказати, скільки символів треба вставити в рядок, щоб жодні два символи підряд не були однаковими.
Щоб два однакові символи підряд перестали бути двома однаковими символами підряд, достатньо вставити поміж них будь-який інший символ. Тому відповідь — кількість пар однакових символів підряд.
Набір кубиків розташовано на прямокутнику, у кожній клітинці прямокутника є декілька кубиків, поскладаних один на одного. Треба вивести послідовність, у якій їх забирати, щоб на кожному кроці кількості кубиків у клітинках утворювали незростаючі послідовності в кожному рядку й у кожному стовпці.
У задачі є багато можливих розв’язків. Наприклад, можна йти по рядках знизу вверх, по кожному рядку справа наліво й повністю забирати всі кубики з клітинок у такому порядку. Легко бачити, що при такому порядку забирання кубиків необхідна умова завжди буде підтримуватися.
Задано набір з \(n\) чисел, кожне з яких від 1 до 4. Потрібно розбити цю множину на дві з однаковою сумою.
Очевидно, для кожної з можливих ваг \((1..4)\) нас цікавить, скільки котів з такою вагою припаде Зенику. Тому достатньо перебрати всі четвірки чисел \((c_1, c_2, c_3, c_3)\), які позначають, скільки котів певної ваги отримає Зеник. Якщо існує четвірка, для якої \(1 \cdot c_1 + 2 \cdot c_2 + 3 \cdot c_3 + 4 \cdot c_4 = \frac{s}{2}\) — розділити котів можна, інакше — ні (тут \(s\) — загальна вага всіх котів).
Задано масив чисел. Видалимо з нього всі такі елементи, що елемент ліворуч від них є більшим. Повторюємо такий процес, поки масив міняється. Треба сказати результуючий масив.
Зрозуміло, що з масиву видаляться всі такі елементи, що десь праворуч від них є більший елемент, а всі решта залишаться. Тому будемо йти справа наліво і підтримувати максимум на суфіксі. Якщо поточне число менше за максимум, то воно видалиться. Інакше воно увійде в результуючу послідовність.
Задано розміри прямокутника, який треба покрити плиткою \(2 \times 1\). Одну з клітинок покривати не можна. Потрібно сказати, чи можна покрити всі клітинки, крім заданої. Якщо так — вивести розбиття.
Неважко побачити, що коли \(n\) або \(m\) є парними, то відповіді не існує. Адже в такому разі загальна кількість клітинок, які потрібно покрити, є непарною, тому це неможливо.
Коли \(n\) та \(m\) є непарними, покриття все ще може бути неможливим (другий тест з умови). Розфарбуємо прямокутник у шаховому порядку. Причому пофарбуємо верхню ліву клітинку в білий колір. У такому разі білих клітинок на одну більше, ніж чорних. Оскільки одна плитка покриває одну білу та одну чорну клітинки — нам потрібно, щоб кіт спав на білій. Клітинка біла, якщо \(x+y\) — парне число.
Якщо ж \(n\) та \(m\) є непарними, а \(x+y\) — парним, прямокутник можна розфарбовувати так. Неважко з правої сторони відрізати смужку довжиною 2:
(Так само можна відрізати смужку розміром 4, 6, 8, ..., тобто будь-яку парну довжину.)
Аналогічно по інших сторонах:
Після цього або вся площа буде закладеною, або ж залишиться квадрат \(3 \times 3\), усередині якого є виділена клітинка. Такий квадрат легко розфарбувати — достатньо розкласти 4 плитки «по колу» від виділеної клітинки.
Задано дерево, у якому \(k\) вершин є позначеними. Потрібно розбити ці вершини на пари так, щоб не було двох пар, для яких шляхи між вершинами перетинаються.
Підвісимо дерево за довільну вершину. Знайдемо найнижчу вершину, для якої кількість позначених вершин у піддереві (включно з нею) більша за один. Тоді зрозуміло, що якщо кількість для цієї вершини є більшою за два, то відповіді не існує, адже хоча б два шляхи точно будуть проходити через цю вершину. Якщо ж ця кількість є рівною 2, то спаруємо ці вершини та видалимо їхні позначення. Цей процес потрібно повторювати, допоки залишаються позначені вершини.
Цей процес найкраще симулювати алгоритмом пошуку в глибину, де рекурсивна функція повертає позначену вершину, яка залишились у піддереві.
Порахуємо ціну за дві пачки гречки без знижки — \(2 \cdot a\), а зі знижкою — \(b\). Отже, ми зекономимо \(2 \cdot a - b\).
Пройдемо циклом по всіх областях, і якщо кількість хворих у відповідній області більша за межу «червоної» зони, тоді до відповіді додаємо одиницю.
Нехай \(p_i\)-е ребро злитка лежить уздовж \(i\)-ого ребра валізи. Тоді для всіх \(i\) має виконуватися \(a_{p_i} \le b_i\). Переберемо всі можливі перестановки \(p\) та перевіримо, чи виконується ця умова хоча б для однієї з них.
D. Шифрування корупційних схем
Достатньо реалізувати алгоритм, описаний в умові — для кожної серії знайдемо її довжину, виведемо її розмір та сам символ.
E. Дешифрування корупційних схем
У рядку виділимо числа — довжини серій та літери — символи рядка. Кожен символ виведемо потрібну кількість разів.
Використаємо підхід динамічного програмування, а саме \(dp_i\) — максимальна відстань, яку Зенику потрібно буде пройти, за умови, що він має всі довідки від 1 до \(a_i\) і стоїть у кабінеті \(i\). Тоді перебравши наступний кабінет, у який завітає Зеник, можна порахувати відповідь для позиції \(i\). Складність такого підходу — \(O(n^2)\).
Можна показати, що для того, щоб максимізувати відстань, яку пройде Зеник, його варто відправити в крайній кабінет, який видає поточну довідку. Наприклад, якщо він зараз у кабінеті, де видають 2-гу довідку, тоді його відправлять або в найлівіший, або в найправіший кабінет, у якому видають 3-тю довідку. Складність у такому разі стає \(O(n)\).
Використаємо систему неперетинних множин.
Пройдемся по всіх ребрах графа \((u, v)\). Якщо вершини \(u\) та \(v\) належать різним компонентам зв’язності, то просто об’єднаємо їх. Якщо ж вони в одній компоненті, назвемо це ребро зайвим.
Пройдемося по всіх зайвих ребрах \((u, v)\). Якщо в графі є тільки одна компонента зв’язності, то задача розв’язана. Інакше, існує вершина \(w\), що не зв’язна з \(u\). Замінимо дорогу \((u, v)\) на \((u, w)\) та об’єднаємо компоненти, що містять вершини \(u\) й \(w\).
Зауважте, що оскільки \(m \ge n\), відповідь завжди існує.
Розглянемо всі варіанти вибору Василем двох задач:
перша й друга задачі;
перша й третя задачі;
друга й третя задачі.
Якщо хоча б в одному варіанті сума складностей не перевищує 47, тоді
відповідь YES
, якщо ж ні, то відповідь —
NO
.
Оптимальним розливанням соку буде таке:
розлити максимально апельсинового соку людям, які люблять тільки апельсиновий сік;
розлити максимально гранатового соку людям, які люблять тільки гранатовий сік;
розлити залишки соку тим людям, яким подобаються обидва типи.
Порахуємо кількість ям, у яких глибина строго більша ніж \(k\). Нехай їхня кількість — \(y\). За умовою водій може об’їхати \(x\) ям, а досягти точки призначення за
умови, якщо відвалилося не більше ніж одне колесо. Отже, якщо \(x - y \ge -1\), то відповідь
YES
, інакше — NO
.
Спочатку для зручності подвоїмо масив. Порахуємо кількість оливок від першого до \(\frac{n}{2}\)-го куска включно. Зазначимо, що для того, щоб дізнатися кількість оливок від другого до \((\frac{n}{2}+1)\)-го шматка, нам достатньо відняти 1 оливку від теперішньої кількості, якщо вона була на першому шматку, та додати 1 оливку, якщо вона є на \((\frac{n}{2}+1)\)-му шматку. Отже, за один прохід ми можемо порахувати кількість оливок на всіх можливих розділеннях піци. І серед усіх розділень піци взяти те, де є мінімальна можлива кількість оливок.
Переберемо довжину одного з крайніх відрізків, наприклад, правого. Нехай сума всіх елементів із цього відрізка рівна \(x\), а сума всіх інших елементів — \(2 \cdot s\). Доведемо, що для зафіксованого правого відрізка (його розміру), ту частину масиву, яка не входить у правий відрізок, оптимально поділити так, щоб модуль різниці цих двох відрізків був мінімально можливим.
Нехай ми розділили решту масиву на дві половини із сумами \(a\) й \(b\). Без обмежень загальності поставимо \(a \le b\) та \(2 \cdot y = b - a\) Тоді \(a + b = s\), \(a = s - y\), \(b = s + y\).
Тепер розглянемо три випадки взаємного розташування \(x\), \(a\) й \(b\):
\(x \le a \le b\) — тоді відповідь рівна \(b - x = s - x + y\);
\(a \le x \le b\) — тоді відповідь рівна \(b - a = 2 \cdot y\);
\(a \le b \le x\) — тоді відповідь рівна \(x - a = x - s + y\).
У цих випадках \(s\) та \(x\) є константами для зафіксованого правого відрізка. У кожному з них для того, щоб мінімізувати відповідь, потрібно мінімізувати \(y\).
Оскільки всі числа додатні, то оптимальне \(y\) для фіксованого правого відрізка можна знайти бінарним пошуком. Також можна шукати оптимальні розбиття для всіх можливих довжин правого відрізка двома вказівниками.
Зауважимо такий факт: якщо ми можемо зареєструвати всіх учасників за деякий час \(t\), то ми можемо зареєструвати всіх учасників і за час \(t + 1\). Скористаємось ідеєю бінарного пошуку по відповіді. Для цього попередньо відсортуємо за зростанням масив координат організаторів \(a\) та масив координат команд \(b\). Зафіксуємо якийсь час \(t\) та перевіримо, чи можливо за цей час зареєструвати всі команди. Для цього переберемо по черзі кожного організатора та будемо підтримувати вказівник на останню команду, яку може зареєструвати цей організатор, витративши час не більший за \(t\). Якщо вдасться зареєструвати всі команди, то змінимо праву границю для нашого бінарного пошуку, а якщо ні — ліву.
Якщо \(k = 1\), тоді існує єдине розбиття числа \(n\) на степені двійки — двійкове представлення числа.
Нехай ми знаємо розбиття \(n\) на \(a_1, \ldots, a_k\), де \(a_i\) позначає суму карт із кольором \(i\). Кожне таке розбиття відповідає єдиному набору карт, і кожен набір карт відповідає єдиному такому розбиттю, а отже кількість наборів карт, що в сумі дають \(n\) рівна кількості розбиттів \(n\) на \(a_1, \ldots, a_k\). А кількість таких розбиттів — це кількість комбінацій з повтореннями (детальніше про це можна прочитати за посиланням ). Тож кількість комбінацій з повторами рівна \(C_{n+k-1}^{k-1}\) — біноміальному коефіцієнтові, який можна порахувати за заданим модулем багатьма способами.
Виведемо суму цін найдешевших цукерок з кожного мішка.
Якщо \(a > b\), поміняємо \(a\) й \(b\), G
й Y
. Без
обмеження загальності вважаємо, що \(a \le
b\). Виведемо \(b-a\) разів
G
, потім — \(a\) разів
YG
.
Якщо \(n\) і \(m\) — непарні, то площа кухні також непарна, тому не вийде замостити всю підлогу. Нехай тепер хоча б одне із чисел \(n\) і \(m\) парне. Якщо \(m\) непарне, то замостимо підлогу вертикальними плитами, якщо ж парне — горизонтальними.
Паліндром непарної довжини має центральний символ. Переберемо його. Спочатку поточний паліндром складається з одного символа. Будемо розширювати поточний паліндром в обидва боки, поки символ зліва від паліндрома збігається із символом справа від паліндрома. Оновимо відповідь довжиною поточного паліндрома.
Паліндром парної довжини має два однакові центральні символи, а не один. Цей випадок розглядається так само.
Складність розв’язку: \(O(n^2)\).
Проітеруємося по днях, і якщо відповідний день має додатну середню температуру повітря, то виведемо його номер.
Для того, щоб отримати мінімально можливе число, потрібно на кожну позицію поставити мінімально можливу цифру, тобто 0. Проте якщо це перша цифра числа, тоді потрібно поставити 1, бо число не може починатися з 0. Для максимального числа потрібно поставити всюди максимальну цифру, тобто 9.
Нам ніколи не вигідно міняти одне число більше ніж один раз, тому що ми можемо за одну операцію поміняти його на його кінцеве значення. Отже, мінімальна кількість змін рівна \(n\) мінус максимальна кількість елементів, що залишаться незмінними. Нескладно переконатися, що Зеник не може одночасно залишити незмінними числа \(a\) й \(b\), якщо вони різні, тобто він може залишити незмінними тільки однакові елементи. А отже нам потрібно знайти максимальну кількість однакових елементів і тоді від \(n\) відняти цю кількість.
Перестановка довжини \(i\) повинна містити лише числа від 1 до \(i\). Для кожного \(i\) від 1 до \(n\) розглянемо перші \(i\) чисел і подивимося, чи ці числа утворюють послідовний відрізок.
Нехай \(l_i\) — найлівіша позиція серед перших \(i\) чисел, а \(r_i\) — найправіша. Це означає, що елементи від 1 до \(i\) є на проміжку \([l_i, r_i]\). Цей проміжок буде перестановкою тоді й лише тоді, коли він містить лише елементи від 1 до \(i\).
Ми знаємо, що ці елементи там містяться, але необхідно ще забезпечити умову того, що там немає інших елементів. Ця умова рівносильна тому, що на цьому відрізку є рівно \(i\) елементів. Більш формально, якщо \(r_i - l_i + 1 = i\), тоді цей відрізок не містить зайвих елементів і є перестановкою.
Тобто нам достатньо пройтися по всіх \(i\) й для відповідного \(i\) знайти \(l_i\) та \(r_i\). Це нескладно зробити, знаючи \(l_{i - 1}\) і \(r_{i - 1}\). Тепер для кожного \(i\) виконаєм перевірку чи \([l_i, r_i]\) є перестановкою.
Паліндром парної довжини має вигляд \(s+r\), а непарної — \(s+c+r\), де \(s\) — деякий рядок, \(r\) — розвернутий \(s\), \(c\) — деякий символ.
Кожен символ зустрічається однакову кількість разів в \(s\) і \(r\). Якщо символ зустрічається на \(a\) картах, то додамо його \(\left\lfloor \frac{a}{2} \right\rfloor\) входжень до рядка \(s\). Якщо існує символ \(c\), який зустрічається на непарній кількості карт, то виведемо паліндром \(s+c+r\), інакше — \(s+r\).
Спершу треба розглянути тривіальні випадки: круги не перетинаються або один круг міститься в іншому.
На рисунках зображені варіанти розташування кіл. Застосувавши теорему косинусів до трикутника \(O_1AO_2\), отримаємо \(r_2^2=d^2+r_1^2-2 d r_1 \cos \alpha_1\), \(r_1^2=d^2+r_2^2-2 d r_2 \cos \alpha_2\). Звідси можемо знайти кути \(\alpha_1\) і \(\alpha_2\).
Площа перетину кругів — це сума площ двох сегментів. Центральний кут сегмента першого круга — \(\angle AO_1B=2\alpha_1\), площа цього сегмента — \(\left(\alpha_1 - \frac{\sin 2 \alpha_1}{2}\right)r_1^2\) (формула для площі сегмента з Вікіпедії). Площу іншого сегмента знаходимо так само.
Скористаємося підходом динамічного програмування. Якщо ви не знаєте, що це, то радимо прослухати відеолекцію.
Станом динаміки \(dp\) є трійка чисел \((i, mn, mx)\), де \(i\) — скільки сходинок уже подолав Зеник, \(mn\) і \(mx\) — найкоротший і найдовший кроки. Значенням динаміки є кількість способів потрапити в такий стан.
Ініціалізуємо значення \(dp[i][i][i] = 1\) — Зеник зробив один крок на \(i\) сходинок. Зі стану \((i, mn, mx)\) є переходи в стани \((i+j, \min\{mn, j\}, \max\{mx, j\})\), де \(j\) — довжина нового кроку.
Відповіддю на задачу буде сума \(dp[n][mn][mx]\) для всіх \(mn, mx\), що задовольняють умову \(mx - mn \le k\).
Складність розв’язку: \(O(n^4)\).
Нехай \(s_i=\sum_{j=1}^{i-1} a_j\). Пересунути фішку з позиції \(x\) у позицію \(y\) коштує \(|s_y-s_x|\).
Тепер задачу можна переформулювати так. Задано \(n\) точок на прямій, \(i\)-а точка має координату \(s_i\). Починаємо з точки \(s_1=0\). Хочемо відвідати всі та мінімізувати відстань, яку пройдемо.
Очевидно, що оптимально піти до найлівішої точки, потім — до найправішої, або навпаки.
Складність розв’язку: \(O(n)\).
Якщо оцінка за предмет — 10 або більше, то вона вже є відмінною. Якщо ж оцінка — 9 або менше, то для того щоб зробити її відмінною, треба буде заплатити \(10 - p_i\) доларів. Зрозуміло, що вигідно зробити відмінними спершу всі 9, потім всі 8 і т. д.
Для кожної оцінки від 1 до 12 знайдемо кількість предметів з такою оцінкою. Оцінки 10, 11 і 12 відмінні зразу. Решту оцінок переберемо від 9 до 1. Поки залишаються гроші, будемо робити оцінки з предметів відмінними.
Для кожного символа виберемо, на яких позиціях ми будемо його залишати: на парних чи на непарних. Переберемо всі такі варіанти. Для кожного символа є по 2 варіанти, тому загалом різних комбінацій є \(2 ^ 4 = 16\). Для кожної комбінації пройдемося по рядку, залишимо відповідні символи й перевіримо, чи збігається отриманий рядок з рядком \(t\). Якщо одна з комбінацій підійде, то відповідь позитивна, інакше — негативна.
Для кожного кадета порахуємо дві величини: за яку мінімальну ціну можна виштовхати всіх кадетів ліворуч від нього — \(l_i\), і праворуч від нього — \(r_i\), відповідно.
Розглянемо кадетів зліва від \(i\)-ого, які виштовхують когось. Нехай їхні індекси — \(i_1, i_2, \ldots, i_l=i\). Тоді \(i_1\)-ий кадет виштовхує всіх на півінтервалі \(\left[1, i_1\right)\), \(i_2\)-ий виштовхує всіх на \(\left[i_1, i_2\right)\) і т. д. Нехай для деякого \(j\) \(a_{i_j} \ge a_{i_{j+1}}\). Відповідь не стане гіршою, якщо \(i_{j+1}\)-ий кадет виштовхає всіх, кого виштовхував \(i_j\)-ий, а \(i_j\) не буде виштовхувати нікого. Тому існує оптимальна відповідь, у якій \(a_{i_1} < a{i_2} < \dots < a{i_l}\).
Пройдемося по кадетах зліва направо й будемо підтримувати зростаючий стек і рахувати \(l_i\). Поки стек непорожній і останній елемент стеку не менший за поточне значення \(a_i\), «викидаємо» елемент зі стеку й перераховуємо \(l_i\). Після цього «закидаємо» \(a_i\) в стек і перераховуємо \(l_i\). \(r_i\) рахуємо аналогічно до \(l_i\).
Для того щоб порахувати відповідь, переберемо, який підвідрізок з \(k\) кадетів залишиться наприкінці. Таких варіантів буде \(n - k+1\). Для фіксованого початку підвідрізка \(i\) нам потрібно виштовхати всіх кадетів лівіше від \(i\)-ого та всіх кадетів правіше від \((i + k - 1)\)-ого, а отже відповідь для \(i\) буде рівна \(l_i + r_{i+k-1}\). Візьмемо мінімальну відповідь.
Спершу скоротимо дріб, поділивши чисельник і знаменник на їхній найбільший спільний дільник. Оскільки відношення суми червоних до суми чорних рівне \(\frac{p}{q}\), то сума червоних \(r = p \cdot x\), а сума чорних \(b = q \cdot x\), де \(x\) — ціле. Якщо додамо ці дві суми, отримаємо \((p + q) \cdot x\), а з іншого боку, сума чисел від 1 до \(n\) рівна \(\frac{n \cdot(n+1)}{2}\). А отже, нам необхідне \(n\) таке, що \(\frac{n \cdot(n+1)}{2}\) ділиться на \(p + q\).
Знайдемо таке мінімальне \(n\), для якого це виконується. Воно не є більшим за \(2\cdot(p + q)\), бо для \(n = 2\cdot(p + q)\) ця умова виконується. Отже, ми можемо визначити \(x\), а знаючи \(x\) можемо визначити \(r\) і \(b\).
Методом математичної індукції можна довести, що числами від 1 до \(n\) можна подати будь-яку суму від 0 до \(\frac{n \cdot(n+1)}{2}\), а отже можна й подати суму рівну \(r\). Для цього можна брати якомога більше число серед тих, що ми ще не взяли, і таке, щоб загальна сума не перевищила шукану суму.
Для кожної IT-компанії порахуємо найменшу відстань до всіх серверів. Для цього використаємо алгоритм пошуку вшир, але не з одного початкового сервера, а з усіх серверів цієї компанії. Для кожного сервера буде порахована мінімальна відстань до найближчого сервера цієї компанії.
Для кожного питання Зеника ми вже знаємо, за який мінімальний час з \(x_i\)-ої компанії ми можемо надіслати запит на сервер \(y_i\). Залишається перевірити, чи цей час не більший за \(t_i\).
Між двома містами \(i\) та \(j\) можна передати повідомлення, якщо відрізки \([x_i-w_i, x_i+w_i]\) та \([x_j-w_j, x_j+w_j]\) перетинаються або дотикаються. Отже, якщо розглянути такі відрізки, то нам потрібно видалити мінімальну їх кількість, щоб відрізки що залишилися не перетиналися — це рівносильно тому, щоб вибрати максимальну кількість відрізків, що не перетинаються.
Розглянемо найлівіший відрізок, який ми залишили у відповіді. Якщо існує відрізок з меншим правим кінцем, то можна взяти його до відповіді замість того, який зараз найлівіший.
Тоді задачу можна розв’язувати жадібно. Посортуємо всі відрізки за правим кінцем. Пройдемо по них та будемо брати поточний відрізок до відповіді, якщо він не перетинається з останнім з тих, що ми вже взяли.
Нехай \(len\) — сумарна довжина шляхів. Тоді розділимо шляхи на дві групи:
ті, у яких довжина більша за \(B\), таких відрізків буде не більше \(\frac{len}{B}\) — назвемо їх великими;
ті, у яких довжина менша за \(B\) — відповідно назвемо їх малими.
Для \(i\)-того великого шляху порахуємо скільки спільних вершин він має з \(j\)-тим шляхом, позначимо цю величину \(cnt_{ij}\). Для \(i\)-того великого шляху будемо пам’ятати величину, яку ми маємо додати до всіх вершин на ньому — \(add_i\). Також будемо пам’ятати суму всіх елементів цього шляху \(sum_i\). Для кожної вершини \(v\) будемо пам’ятати її поточне значення, не враховуючи оновлень великих шляхів, \(x_v\).
Тоді відповідь для \(i\)-того великого шляху буде рівна \(sum_i\) — складність \(O(1)\).
Для \(j\)-того малого шляху порахуємо суму значень \(x_v\) вершин цього шляху. Щоб знайти суму на ньому, необхідно ще врахувати ті значення, що додають великі відрізки: \(i\)-тий великий відрізок додасть \(cnt_{ij} \cdot add_i\). Складність рівна \(O(B + \frac{len}{B})\), адже потрібно пройтися по всіх вершинах шляху (не більше ніж \(B\)) і по кожному великому шляху, а великих шляхів не більше ніж \(\frac{len}{B}\).
Тепер нам потрібно порахувати значення \(cnt_{ij}\) і вміти підтримувати параметри \(x_v\) i \(sum_i\).
Для \(i\)-того великого шляху позначимо всі його вершини, тоді переберемо \(j\)-тий шлях і проітеруємося по його вершинах, і якщо вершина помічена, тоді виконаємо \(cnt_{ij} := cnt_{ij} + 1\).
Якщо приходить \(+ val\) до \(j\)-того шляху тоді для \(i\)-того великого шляху зробимо \(sum_i := sum_i + cnt_{ij} \cdot val\). Якщо \(i\)-ий шлях великий, тоді нам треба ще оновити \(add_i := add_i + val\). Якщо ж малий, тоді потрібно пройтися по всіх його вершинах \(v\) і виконати \(x_v := x_v + val\). Складність — \(O(\frac{len}{B}\) i \(O(\frac{len}{B} + B)\) для великого і малого шляху відповідно.
Отже, складність для одного запиту рівна \(O(\frac{len}{B} + B)\), сумарна складність рівна \(O(k \cdot (\frac{len}{B} + B) + n \cdot B)\). Якщо вибрати \(B^2 = len\) тоді загальна складність \(O((n + k) \cdot \sqrt {len})\).
Перевіримо, чи \(a+b>c\).
Кількість кожного дня тижня буде хоча б \(\left \lfloor \frac{n}{7} \right \rfloor\), бо до дедлайну пройде стільки повних тижнів. Крім цього, до \(n \% 7\) (остача від ділення) днів від сьогодні додамо одиницю.
Для того щоб робот міг потрапити в точку \((x, y)\) необхідно й досить, щоб кількість
символів R
була хоча б \(x\), а кількість U
— хоча б
\(y\). Тоді можна поставити ці символи
на початок рядка, і після \(x+y\)
команд робот опиниться в точці \((x,
y)\).
Є два варіанти кінцевої стрічки: або вона починається синьою частиною, або жовтою. Колір першої частини однозначно визначає всю стрічку, тому що кольори повинні чергуватися. Переберемо, який із цих двох варіантів буде кінцевим, і для кожного знайдемо кількість частин, колір яких треба змінити. Виведемо мінімальне значення.
Відповідь дорівнює кількості суцільних відрізків з однакових символів. Така кількість відрізків рівна \(n\) - (кількість сусідніх пар однакових символів).
Переберемо всі пари стад блакитного й жовтого кольорів, знайдемо площу перетину їхніх прямокутників. Виведемо пару, для якої площа перетину максимальна.
Якщо НСК\((a, b) = x\), то \(a\) й \(b\) є дільниками \(x\). Переберемо всі пари дільників \((a, b)\) та перевіримо, чи найменше спільне кратне цих чисел дорівнює \(x\).
Більше про дільники можна дізнатися в цьому відео, а про НСК — у цьому.
D. Дзідзьо й зустріч з фанатами
Нехай, без обмеження загальності, \(n \le m\). Якщо \(n=1\) і \(m\) непарне, то відповідь — 3. Якщо \(n=1\) і \(m\) парне, то відповідь — 2. Якщо \(n>1\), то відповідь — 0. Для кращого розуміння дивіться рис. 1.
Довжина найбільшого числа — \(\left \lceil \frac{n}{k} \right \rceil\).
Будемо будувати найбільше число зліва направо. При цьому підтримуватимемо \(c\) — кількість чисел, які ще можуть бути найбільшим. Початково \(c\) — кількість чисел завдовжки \(\left \lceil \frac{n}{k} \right \rceil\). \(c = n \% k\), якщо це значення ненульове, інакше \(c=k\).
\(\left \lceil \frac{n}{k} \right \rceil\) разів треба дописати до поточного найбільшого числа якомога меншу цифру. Маємо \(c\) чисел, які поки що є найбільшими. Візьмемо \(c\) найменших невикористаних цифр. Допишемо їх до цих найбільших чисел. Нехай найбільша цифра, яку ми щойно використали — \(d\), і ми використали її \(c'\) разів. \(c'\) буде новим значенням \(c\). Виведемо цифру \(d\).
Якщо Кирило першим ходом узяв паличку завдовжки \(a_i\), то Змій повинен узяти паличку завдовжки \(a_j\), щоб незалежно від того, яку третю паличку завдовжки \(a_k\) вибере Кирило, з них можна було скласти невироджений трикутник. Для всіх \(k \ne i, k \ne j\) повинні виконуватися нерівності трикутника: \(a_i < a_j + a_k, a_j < a_k + a_i, a_k < a_i + a_j\). Перепишемо ці нерівності так: \[a_j > a_i - a_k, a_j > a_k - a_i, a_j < a_k + a_i.\]
Нехай найкоротша паличка, крім \(i\)-ої, має довжину \(a_{min}\), а найдовша — \(a_{max}\). Перевіримо, чи існує таке \(j\), що \[a_j > a_i - a_{min}, a_j > a_{max} - a_i, a_j < a_{min} + a_i.\] Якщо існує, то таке \(j\) і буде виграшним ходом для Змія.
Нерівності \((1)\) мають виконуватися для \(k \ne j\), а в перевірці ми цього не забезпечуємо й маємо сильнішу умову \((2)\). Можна просто окремо перевірити, чи виграє Змій якщо візьме паличку \(a_{min}\) чи \(a_{max}\).
Однак можна показати, що цих додаткових перевірок не потрібно. Для цього достатньо довести такі дві леми.
Якщо Змій може виграти, взявши паличку \(a_{min}\), то він може виграти, взявши паличку \(a_{max}\).
Якщо Змій може виграти, взявши паличку \(a_{max}\), то для неї будуть виконуватися нерівності \((2)\).
Доведення залишаємо вправою.
Скористаємося підходом динамічного програмування. Детальніше про динамічне програмування можна дізнатися у відео.
Нехай \(dp[i][j][c]\) — мінімальна кількість клітинок, яку повинна подолати Коза, щоб опинитися в клітинці \((i, j)\), відвідавши \(c\) клітинок з травою. Зі стану \((i, j, c)\) є перехід у стан \((i+1, j, c)\), якщо в клітинці \((i+1, j)\) нема трави, і в стан \((i+1, j, c + 1)\) в іншому разі. Так само є переходи в клітинку \((i, j+1)\).
Відповіддю на задачу є \(\min_{i, j} dp[i][j][k]\).
Для кожного запиту будемо підтримувати кінці шляху \(a\), \(b\). Початково це дві перші вершини шляху.
Розглядаємо відвідану Колобком вершину \(p\).
Якщо \(p\) лежить на шляху від \(a\) до \(b\), то нічого не порушується, у цьому разі нічого не робимо.
Якщо \(b\) лежить на шляху від \(a\) до \(p\), то \(p\) стає новим кінцем шляху, присвоюємо \(b:=p\).
Якщо ж \(a\) лежить на шляху від \(b\) до \(p\), то аналогічно \(a:=p\).
Якщо не виконується жодна з трьох вищенаведених умов, то Колобок не міг відвідати на одному шляху вершини \(a\), \(b\) й \(p\). У цьому разі виведемо
Ni
.
Якщо ми розглянули всі вершини й не вивели Ni
, то
Колобок міг їх відвідати. Тоді виведемо Tak
.
Залишилося навчитися перевіряти, чи лежить деяка вершина \(x\) на шляху від \(a\) до \(b\). Підвісимо дерево за довільну вершину. Нехай \(c\) — найменший спільний предок вершин \(a\) й \(b\). Критерій того, що \(x\) лежить на шляху від \(a\) до \(b\) — \(c\) є предком \(x\) і (\(x\) є предком \(a\) або \(x\) є предком \(b\)).
Марічці треба залишити в кожній пачці по одному печиву. Відповіддю буде сума всіх \((a_i-1)\) або сума всіх \(a_i\) мінус \(n\), що є тим самим.
Спершу зауважимо, що задачу можна розв’язувати окремо для борщу, картоплі й салату. Розв’яжемо для борщу.
Нехай ми дали кожному другові по \(x\) грамів борщу. Якщо почати збільшувати \(x\), то в тих друзів, у яких \(a_i \le x\) ступінь недовіри почне зростати, а в тих, у кого \(a_i > x\) — спадати. Аналогічно, якщо почати зменшувати \(x\), у кого \(a_i \ge x\) зростатиме недовіра, а в кого \(a_i < x\) — спадатиме. Щоб \(x\) був оптимальним розв’язком, необхідно, щоб при малому збільшенні чи зменшенні \(x\) сумарний ступінь недовіри не спадав (бо інакше можна було б змінити \(x\) і отримати кращий розв’язок). Кількість друзів, у яких спадає недовіра, має не перевищувати кількість друзів, у яких вона зростає.
Оптимальним \(x\) буде медіана \(a\). Пояснимо детальніше. Нехай \(a'\) — посортований масив \(a\). Якщо \(n\) непарне, то оптимальним \(x\) буде \(a'_{\frac{n+1}{2}}\). Якщо ж парне, то оптимальним буде будь-який \(x\), що задовольняє \(a'_{\frac{n}{2}} \le x \le a'_{\frac{n}{2}+1}\). Доведіть це самостійно.
Незалежно від парності \(n\) можна
взяти \(x=a'_{\left\lfloor \frac{n+1}{2}
\right\rfloor}\). Для цього можна посортувати масив або
використати функцію nth_element
у C++.
Виведемо сумарний ступінь недовіри для борщу, картоплі й салату.
Для кожного \(a_i\) переберемо всі його дільники \(x\). Знайдемо кількість таких дільників, що \(a \le x \le b, c \le \frac{a_i}{x} \le d\). Позначимо цю кількість \(p\). \(q=(b-a+1)(d-c+1)\) — кількість усеможливих пар чисел, які можуть назвати Зеник і Марічка. Виведемо \(\frac{p}{q}\).
При повороті карти інваріантом (тим, що не змінюється) є довжини відрізків між сусідніми контрольними точками маршруту та кути між цими відрізками.
Нехай \(P_i\) — точки маршруту. Тоді \(i\)-у точку можна охарактеризувати такими величинами: довжинами відрізків \(P_{i-1}P_i\), \(P_iP_{i+1}\), скалярним добутком \(\overrightarrow{P_{i-1}P_i} \cdot \overrightarrow{P_iP_{i+1}} = P_{i-1}P_i \cdot P_iP_{i+1} \cdot \cos \alpha_i\) та векторним добутком \(\overrightarrow{P_{i-1}P_i} \times \overrightarrow{P_iP_{i+1}} = P_{i-1}P_i \cdot P_iP_{i+1} \cdot \sin \alpha_i\), де \(\alpha_i\) — кут між векторами \(\overrightarrow{P_{i-1}P_i}\) та \(\overrightarrow{P_iP_{i+1}}\). Оскільки довжини й кути не змінюються при повороті, то в точок на мапах, що відповідають за ту саму контрольну точку, ця четвірка величин буде однакова.
Позначимо четвірку величин для \(i\)-ої точки на мапі Зеника \(s_i\), а на іншій мапі — \(t_i\). Тоді задача зводиться до такої. Задано рядки \(s=s_1s_2 \ldots s_n\), \(t=t_1t_2 \ldots t_n\). Відомо, що \(s\) є циклічним зсувом \(t\). Треба знайти, на скільки позицій треба циклічно зсунути \(s\), щоб вийшло \(t\).
Потрібно в рядку \(s+s\) знайти \(t\) як підрядок. Задача знаходження рядка в підрядку є стандартною. Її можна розв’язувати, наприклад, алгоритмом Кнута—Морріса—Пратта (укр., англ.) або алгоритмом Рабіна—Карпа (укр., англ.).
A. Існує дві дороги: Одна пряма, а інша …
Для кожної дільниці та відповідного їй регіонального представництва порахуємо відстань між ними за теоремою Піфагора: \[\sqrt{(x_1 - x_2)^2 + (y_1 - y_2)^2}\]
Відповідь рівна сумі всіх цих відстаней.
Якщо існує урна, в якій більше ніж \(k\) бюлетенів, то відповідь
-1
. Інакше знайдемо мінімальну кількість членів комісії
\(cnt\), якої достатньо для опрацювання
всіх урн.
Для цього скористаємось жадібним алгоритмом: перший член комісії візьме максимальну кількість урн, починаючи з першої, в яких в сумі не більше ніж \(k\) бюлетенів, другий візьме максимальну кількість урн починаючи з наступної неопрацьованої і т.д.
Відповідь рівна \(n - cnt\) якщо
\(cnt \le n\), або ж -1
,
якщо \(cnt > n\).
Час в форматі \(hh:mm:ss\) можна перетворити в номер секунди від початку доби за формулою \[t = hh \cdot 60 \cdot 60 + mm \cdot 60 + ss\]
Для кожної секунди в добі, порахуємо скільки виборців знаходились на дільниці в цю секунду.
Для цього будемо підтримувати масив \(cnt'_i\). Для кожного виборця знайдемо секунду в яку він прийшов на дільницю \(from\) та секунду в яку він покинув дільницю \(to\). Збільшимо \(cnt'_{from}\) на одиницю та зменшимо \(cnt'_{to}\) на одиницю.
Після опрацювання всіх виборців обчислимо \(cnt\): масив префіксних сум масиву \(cnt'\). Тобто \[cnt_i = \sum_{j = 0}^{i} cnt'_j\] Тепер \(cnt_i\) дорівнює кількості виборців які прийшли на дільницю до моменту часу \(i\) включно, та покинули її строго після \(i\), тобто кількість виборців які знаходились на дільниці в цю секунду.
Відповідь це кількість секунд між 8:00:00 та 20:00:00 не включно, в які кількість виборців на дільниці рівна нулю.
Складність алгоритму \(O(n + t)\), де \(t\) - кількість секунд в добі.
Також існує розв’язок за \(O(n \cdot \log{n})\).
Розвернемо рядки \(p\) та \(r\). Отримані рядки назвемо \(p'\) та \(r'\) відповідно.
Тепер задача полягає в знаходженні найменшої кількості префіксів рядка \(p'\) які в конкатенації дають рядок \(r'\).
Для зручності також позначимо довжину рядків \(p'\) та \(r'\) як \(n\) та \(m\) відповідно.
Доведемо, що існує оптимальна відповідь, в якій довжина останнього префіксу максимально можлива. Для цього розглянемо два різних суфікси \(r'[i..m - 1]\), та \(r'[j..m - 1]\), де \(i < j\), причому обидва суфікси є префіксами рядка \(p'\). Нехай оптимальна відповідь містить префікс \(r'[j..m - 1]\). Замінимо в цій відповіді останній префікс на \(r'[i..m - 1]\), кількість елементів в відповіді при цьому не зміниться. Тепер існує відрізок \(r'[i..j - 1]\), кожен символ в якому покритий двома префіксами \(p'\). Всі старі префікси які повністю містяться в відрізку \([i..j - 1]\) тепер можна викинути, кількість елементів в відповіді від цього може тільки зменшитись. А єдиний префікс \(r'[l..k]\), такий що \(l < i \le k\), тобто такий, що його частина покривається префіксом \(r'[i..m - 1]\), може бути замінений на префікс \(r'[l..i - 1]\), тому що якщо \(r'[l..k]\) — префікс \(p'\), то \(r'[l..i - 1]\) — також префікс \(p'\). В результаті такої заміни кожен елемент з \(r'\) буде покритий рівно одним префіксом, і кількість префіксів збільшитись не може. А отже в результаті такого процесу можна будь-яку відповідь перетворити до вигляду коли останній префікс має максимально можливу довжину, в тому числі і оптимальну відповідь. Зафіксувавши останній префікс, можна аналогічними міркуваннями почати збільшувати довжину передостаннього і т.д.
В результаті одна з оптимальних відповідей може бути побудована таким жадібним алгоритмом: знаходимо найбільший префікс рядка \(p'\) який співпадає з суфіксом рядка \(r'\), тоді видаляємо цей суфікс, і збільшуємо відповідь на 1. Повторюємо цей процес поки рядок \(r'\) не стане порожнім.
Для того щоб навчитися швидко знаходити найбільший суфікс рядка \(r'\), який співпадає з префіксом рядка \(p'\) можна використовувати префіксну функцію. А саме: обчислимо префіксну функцію \(\pi\) від рядка \(p' + \$ + r'\). Тоді довжина найдовшого префікса \(p'\) який співпадає з суфіксом \(r'\) буде значенням \(\pi\) на позиції \(n + m\). Оптимальні довжини всіх наступних префіксів можна знайти в тому ж масиві по черзі віднімаючи від позиції довжину останнього префіксу.
Складність алгоритму \(O(n + m)\).
Потрібно знайти найменший з вимірів ящика. Це і буде діаметром максимальної сфери, яка поміститься.
Складність розв’язку — \(O(1)\).
Нам задано перший та тринадцятий члени арифметичної прогресії. З означення арифметичної прогресії, ми знаємо, що \(A_k = A_1 + (k-1) \cdot d\), де \(A_i\) - \(i\)-тий член арифметичної прогресії, а \(d\) її різниця. З цієї формули випливає, що \(d = \frac{A_k - A_1}{k-1}\), що для \(k=13\) дає \(d = \frac{A_{13} - A_1}{12}\).
Зрозуміло, що усі члени арифметичної прогресії є цілими лише у випадку, якщо перший член і різниця цієї прогресії є цілими. Умова гарантує, що перший член є цілим, а тому нам треба перевірити лише різницю. Тобто, перевірити чи \(B-A\) ділиться без остачі на 12.
Якщо різниця є цілою (зауважте, що вона може бути й від’ємною, це ні на що не впливає), то нам потрібно знайти суму перших тринадцяти членів цієї прогресії. Загальновідома формула для суми перших \(k\) членів — \(S_k = \frac{(A_1 + A_k) \cdot k}{2}\), а тому відповідь на задачу це \(\frac{(A+B) \cdot 13}{2}\).
Складність розв’язку — \(O(1)\).
Усіх людей за столом можна розділити на проміжки (тут проміжком називається множина людей, що сидять підряд), такі що кожен проміжок є або повністю зараженим, або повністю не зараженим. Зауважте, що оскільки стіл круглий, то перший учасник є сусідом останнього. Наприклад, стіл з восьми учасників {0 1 1 0 0 0 1 0} ділиться на 4 проміжки:
незаражений проміжок довжини 2, що включає першого та останнього учасника,
заражений проміжок довжини 2, що включає другого та третього учасника,
незаражений проміжок довжини 3, що включає учасників з четвертого по шостого,
заражений проміжок довжини один, що включає лише сьомого учасника.
.
Зрозуміло, що кожен незаражений проміжок ставатиме коротшим на два кожної хвилини, оскільки два крайні учасники заразяться від сусідніх заражених. Тобто, проміжок довжини \(k\) повністю заразиться за \(\lceil \frac{k}{2} \rceil\) хвилин. Усі учасники за столом захворіють, як тільки повністю заразиться найдовший з незаражених проміжків.
Отже, все що потрібно зробити — це знайти довжину найдовшого незараженого проміжку за круглим столом. Один зі способів це зробити такий: повторимо початковий масив двічі і просто знайдемо довжину найдовшого незараженого проміжку так, якби учасники сиділи не за круглим столом, а просто в рядок.
Складність розв’язку — \(O(n)\).
Припустимо, що в нас є необмежений запас вакцини першого типу, але лише одна вакцина другого типу. Якщо ми всім дамо вакцину першого типу, то сумарна користь становитиме \(A_1 + A_2 + ... + A_n\). Якщо \(i\)-тій людині ми дамо вакцину другого типу, замість першого, то ця користь зміниться на \(B_i - A_i\). Отже, вакцину другого типу є зміст давати лише учаснику в якого \(B_i - A_i\) максимальне і лише в випадку, коли \(B_i - A_i\) додатне для нього.
Аналогічно, якщо в нас є лише дві дози другої вакцини, то їх може бути зміст давати лише двом учасниками з найбільшими значеннями \(B_i - A_i\).
Узагальнюючи ці міркування, отримуємо повний розв’язок. Впорядкуємо всіх учасників за незростанням \(B_i - A_i\). Другу вакцину отримає деяка група людей, що стоїть на початку в цьому посортованому списку. Треба лише визначити скільком людям на початку списку вигідно дати другу вакцину. Очевидно, що ідеально було б дати вакцину другого типу усім в кого значення \(B_i - A_i\) додатне, а решті дати вакцину першого типу. Але у цьому випадку нам може не вистачити вакцин одного з типів. А тому треба також врахувати, що другу вакцину ми маємо дати не менше ніж \(n - x\) учасникам та не більше ніж \(y\) учасникам.
Складність розв’язку — \(O(n \log(n))\).
Якщо сума всіх елементів масиву парна, то Зеник виграє перших ходом. В іншому випадку, якщо Зеник залишить суму елементів непарною, Марічка виграє своїм наступним ходом. Щоб цього уникнути, Зенику потрібно своїм ходом обов’язково змінити парність суми масиву. Єдиний спосіб це зробити — взяти деякий відрізок парної довжини з непарною сумою, та замінити всі елементи в ньому на одинички. Тоді сума всіх елементів масиву зміниться з непарної на парну. Це єдиний спосіб Зенику уникнути негайного програшу після наступного ходу Марічки.
Зауважимо, що роблячи такий хід, Зеник збільшує кількість одиничок в масиві. Якщо Марічка буде дотримуватимуться такої ж стратегії, то кількість одиничок буде збільшуватися після кожного ходу, а тому, рано чи пізно, всі елементи стануть одиничками, і переможе Марічка. Тобто, незалежно від своїх ходів, Зеник не має жодного шансу на перемогу.
Отже, переможець гри однозначно визначається парністю суми всіх елементів масиву.
Складність розв’язку — \(O(n)\).
Нехай \(n\) — довжина рядка \(T\), а \(m\) — довжина рядка \(S\).
Якщо \(n < m\), то відповідь 0, адже ми не можемо знайти жодного підрядка потрібної довжини у \(T\).
Подивимося який вклад у загальну відповідь внесе перший символ рядка \(S\): він додасть до відповіді 1 за кожен такий же символ рядка \(T\), де може починатися підрядок довжини \(m\) (тобто символи від 1 до \(n-m+1\)). Аналогічно, другий символ рядка \(S\) додасть до відповіді 2 за кожен такий же символ \(S\) з проміжку від 2 до \(n-m+2\).
Узагальнюючи, отримуємо, що вклад \(i\)-го символу рядка \(S\) у відповідь становитиме \(i \cdot count_T(S_i, i, n-m+i)\), де \(count_T(x, l, r)\) — це кількість символів \(x\) у рядку \(T\) на проміжку від \(l\) до \(r\).
Отож, якщо ми навчимося швидко шукати \(count_T(x, l, r)\), то задача розв’язана. Зауважимо, що у рядка, який складається з малих літер латинської абетки може бути щонайбільше 26 різних символів.
Заведемо двовимірний масив розміром \(26 \times n\). Нехай \(A_{i,j} = 1\), якщо \(j\)-й символ рядка \(T\) є \(i\)-тим символом алфавіту. Тепер, щоб знайти \(count_T(x, l, r)\) нам потрібно знайти суму на відповідному відрізку одновимірного масиву \(A_{i}\). Для цього скористаємося відомим методом, який називається часткові суми.
Нехай \(B_{i,j} = A_{i,1} + A_{i,2} + ... + A_{i,j} = B_{i, j-1} + A_{i, j}\). Тепер, зрозуміло, що \(count_T(x, l, r) = A_{i,l} + A_{i,l+1} + ... + A_{i,r} = B_{x, r} - B_{x, l-1}\).
Отже, обчисливши один раз масив \(B\) зі складністю \(O(26 \cdot n)\), ми зможемо знаходити \(count_T(x, l, r)\) за \(O(1)\). Загальна складність розв’язку — \(O(26 \cdot n)\).
Яка довжина найкоротшого шляху, що починається в корені дерева проходить через усі листки дерева, а тоді повертається у корінь? Легко бачити, що такий шлях проходить по кожному ребру рівно 2 рази, а тому його довжина — \(2n - 2\), де \(n\) — кількість вершин у дереві.
Як змінюється ця довжина якщо нам не потрібно повертатися в корінь після відвідування останнього листка? Нехай \(D_v\) — відстань від кореня до вершини \(v\) (ми також називатимемо цю величину глибиною вершини \(v\)). Зрозуміло, що закінчивши у листку \(x\), ми економимо рівно \(D_x\) ребер. Отже, вигідно закінчити наш маршрут у вершині, для якої \(D_v\) максимальне.
Таким чином, щоб відповісти на запит другого типу нам потрібно знати кількість вершин у піддереві, а також глибину найглибшого листка. Якби не було запитів першого типу, то було б достатньо обчислити ці значення для усіх вершин за допомогою пошуку в глибину. Як же бути з запитами першого типу? Від задачі з додаванням вершин перейдемо до задачі з "увімкненням" вершин. Розглянемо дерево, що вийде після виконання усіх запитів першого типу (ми називатимемо його фінальним деревом). Тепер вважатимемо, що кожна вершина в цьому дереві може бути або увімкненою, або ні. Коли відбувається запит першого типу, то ми вмикаємо відповідну вершину. Для запиту другого типу нам потрібно знайти кількість увімкнених вершин у піддереві та максимальну глибину серед увімкнених вершин у піддереві.
Побудуємо Ейлеровий обхід фінального дерева: випишемо усі вершини дерева в порядку обходу в глибину. Кожному піддереву відповідає деякий неперервний відрізок в цьому обході. Це дозволяє перетворити запити на піддереві у запити на відрізку. Отож, тепер нам потрібна структура даних, що ефективно виконує такі операції:
змінити значення елемента (щоб увімкнути вершину)
знайти суму на відрізку (щоб знайти кількість вершин у піддереві)
знайти максимальний елемент на відрізку (щоб знайти найглибшого листка)
Одна з таких структур — дерево відрізків. Вона може виконувати кожен з цих запитів з логарифмічною складністю.
Загальна складність — \(O(n + q \log(n))\).
Під час кожного ходу рівно одна біла клітинка зафарбовується в чорний колір. Отже, загальна кількість ходів рівна кількості білих клітинок на дошці. На дошці є \(n \cdot m\) білих клітинок. Якщо ця кількість парна, то Дракон зробить останній хід і переможе в грі. Інакше переможе Бісеня.
Пройдемось по масиву зліва направо і будемо підтримувати \(cur\) — кількість послідовних елементів більших або рівних за \(k\), закінчуючи в цій позиції включно. Якщо черговий елемент \(x \ge k\), то \(cur\) збільшується на один, інакше \(cur\) стає рівним нулю. Відповідь буде максимум зі значень \(cur\) в кожній позиції масиву.
Порахуємо \(distances_i\) — відстань від хатинки сеньйора до \(i\)-тої точки, де дракон дмухав вогнем. Після цього впорядкуєм масив \(distances\). Відповідь рівна значенню \(distances_k\) у відсортованому масиві.
В C++ замість сортування можна використати стандартну функцію
std::nth_element
, яка дозволяє за лінійний час знайти, яке
значення було б на певній позиції, якби масив впорядкували.
Одну з оптимальних послідовностей операцій можна побудувати наступним чином.
Якщо у матриці кожен зі стовпців має вигляд RR
або
BB
, то кожен стовпець BB
може бути замінений
на RR
за одну операцію другого типу. В такому випадку
відповідь буде рівна кількості стовпців BB
.
В іншому випадку в матриці існують стовпці RB
або
BR
. В такому випадку жадібно розіб’ємо матрицю на відрізки
по стовпцях так, щоб в кожному відрізку не було одночасно стовпців
RB
та BR
. Нехай всього таких відрізків є \(x\). Тоді за \(\lfloor \frac{x} {2} \rfloor\) операцій
можна замінити всі RB
(або BR
, в залежності
від того яких відрізків менше) на RR
застосувавши операцію
третього типу до відповідного відрізка. Після чого за ще одну операцію
можна замінити всі BR
(або RB
, в залежності
від того, які стовпці залишились) на RR
застосувавши
операцію третього типу до всієї матриці. Після цього ще можуть
залишитись стовпці вигляду BB
, кожен з яких можна
замінитина RR
послідовно застосовуючи операцію другого типу
до пари сусідніх стовпців RR
та BB
.
Доведення оптимальності залишаємо читачу.
Час роботи жадібного алгоритму \(O(n)\).
Також існує розв’язок за допомогою динамічного програмування за \(O(n^3)\).
Код розв’язку C++ методом динамічного програмування за \(O(n^3)\)
Щоб розшифрувати повідомлення потрібно зробити зворотний процес до того, який зробив Зеник для шифрування. Розглянемо один із простих в реалізації способів.
Розділимо зашифроване повідомлення на \(k\) рядків. Отримали матрицю \(k \times k\). Всього в матриці є \(2 \cdot k - 1\) діагональні лінії, \(x\)-а з яких складається з елементів матриці \(A_{i,j}\), таких що \(x = i + j\) та \(0 \le i, j < k\). Переберемо спочатку номер лінії \(x\) (від 0 до \(2 \cdot k - 2\)), а потім \(i\) (від 0 до \(k - 1\)), знаючи \(x\) та \(i\) можна легко визначити \(j = x - i\). Якщо отримане \(j\) знаходиться в межах від 0 до \(k - 1\), то відповідний елемент матриці потрібно додати до відповіді.
Переберемо верхній лівий одиничний квадрат та довжину сторони великого квадрата. Для кожного такого великого квадрата порахуємо кількість одиниць в ньому. Відповідь рівна максимуму з довжин великого квадрата серед усіх таких квадратів в яких кількість одиниць не перевищує \(k\).
Час роботи алгоритму \(O(n^5)\) і цього достатньо для обмежень в задачі.
Також існують розв’язки за \(O(n^3)\) та \(O(n^2 \cdot \log{n})\)
Побудуємо граф, вершинами якого будуть учні. Дві вершини з’єднаємо ребром, якщо відповідні учні дружать між собою.
Тепер можна сформулювати задачу наступним чином: Петрик (якому відповідає вершина з номером 1) може намовити голосувати за Христину всіх учнів, які знаходяться в його компоненті зв’язності. Скількома способами Зеник може видалити ребро з графу так, щоб в компоненті зв’язності Петрика стало менше ніж \(n\) вершин?
Нескладно побачити, що задача полягає в знаходженні кількості мостів у графі. Тобто таких ребер, при видаленні яких граф розпадеться на дві компоненти зв’язності.
Розглянемо простий спосіб знаходження мостів в графі. Переберемо ребро, яке видалить Зеник. Тепер видалимо його з графу, і запустимо обхід в глибину з будь-якої вершини. Якщо в процесі цього обходу будуть відвідані не всі \(n\) вершин, то це означає що видалене ребро є мостом. В такому випадку додамо один до відповіді. Важливо не забути повернути ребро назад перед розглядом наступного ребра.
Час роботи такого алгоритму \(O(m \cdot (n + m))\), чого достатньо для даних обмежень.
Також існує спосіб знаходити мости в графі за \((n + m)\).
Застосуємо метод динамічного програмування. Нехай \(dp[pos][nonzero][less][mask]\) дорівнює кількості способів побудувати префікс числа яке не перевищує \(n\) довжини pos, використовуючи цифри які входять в бітову маску \(mask\).
Параметр \(less\) рівний 0, якщо префікс повністю збігається з відповідним префіксом n, або 1, якщо префікс лексикографічно менший. Параметр \(nonzero\) рівний 1, якщо на префіксі вже є ненульова цифра, або 0, якщо таких немає.
Ініціалізація проста — \(dp[0][0][0][0] = 1\), всі інші стани рівні нулю.
Для зручності позначимо як \(s[i]\) \(i\)-тий символ в десятковому записі числа \(n\) (нумеруємо з 0, зліва направо).
Розглянемо переходи зі стану \(dp[pos][nonzero][less][mask]\). Якщо \(less\) рівний нулю, то на цю позицію можна поставити лише цифру яка не перевищує \(s[pos]\). Інакше, оскільки наше число вже менше за \(n\), то на цю позицію можна поставити будь-яку цифру від 0 до 9. Переберемо цифру яку будемо ставити на цей розряд. Нехай ми хочемо поставити цифру \(d\). Знайдемо нову маску з цифр \(nmask\). Вона дорівнює старій масці із включеним бітом для цифри \(d\). Оскільки ми не хочемо будувати числа з ведучими нулями, то якщо наш префікс складається лише з нулів (\(nonzero\) дорівнює 1) біт для цифри 0 включати в нову маску не будемо. Нове значення параметру \(less\) обчислити просто: якщо \(less\) вже був 1, то й залишиться 1. Інакше \(less\) стане рівне 1 тільки якщо \(d < s[pos]\). Параметр \(nonzero\) буде рівний 1, якщо він вже рівний 1, або ж якщо \(d \neq 0\). Параметр \(pos\) при збільшенні довжини префіксу на 1 стане рівним \(pos + 1\).
Після цього для зручності порахуємо \(cnt[mask]\) - кількість чисел, які не перевищують \(n\), та складаються з цифр із маски \(mask\). \(cnt[mask]\) дорівнює сумі \(dp[|s|][nonzero][less][mask]\) по всіх можливих значенням параметрів \(nonzero\) та \(less\) (0 або 1).
Тепер розглянемо всі пари масок \(a\) та \(b\). Якщо ці маски мають спільний біт, то відповідні числа мають спільні цифри. В такому випадку, до відповіді потрібно додати добуток \(cnt[a] \cdot cnt[b]\), тому що існує саме стільки пар чисел з відповідними наборами цифр.
В процесі роботи алгоритму буде обчислено не більше ніж \(11 \cdot 2 \cdot 2 \cdot 1024 = 45056\) станів динамічного програмування, з кожного з них буде не більше 10 переходів, що в сумі дасть не більше ніж 450560 переходів з невеликою константою. Після цього потрібно розглянути \(1024^2\) пар масок. Загальна кількість операцій не перевищує кількох мільйонів, що з легкістю вкладається в обмеженя задачі.
Знайдемо найменше число \(x = 10^n\) таке, що \(x \ge l\). Якщо \(x \le r\) то відповідь \(x\). Інакше числа \(l\) та \(r\) складаються з однакової кількості цифр. В такому випадку лексикографічне порівняння не відрізняється від звичайного, а отже лексикографічно найменшим числом з відрізка від \(l\) до \(r\) буде число \(l\).
Будь-яке парне число оптимально подати у вигляді послідовності з
\(\frac{s} {2}\) двійок. Непарні числа
менші за 9 можна подати тільки одним числом \(s\). Число 9 найоптимальніше подати у
вигляді 3, 3, 3
. Непарні числа більші за 9 вигідно подати у
вигляді послідовності 3, 6, 2, 2, 2…
, тобто кількість чисел
буде рівна \(2 + \frac{s - 9}
{2}\).
Позначимо вхідний рядок змінною \(s\). Нехай \(t\) — лексикографічно мінімальний рядок який можна отримати перестановкою букв \(s\), тобто \(t\) — рядок \(s\) у якому елементи впорядковані за неспаданням.
Рядок \(t\) — найкраща можлива відповідь для задачі, оскільки він є найменшим лексикографічним рядком, котрий можна отримати перестановкою букв вхідного рядка. Проте, для того щоб отримати рядок \(t\), можливо, необхідно вирідати більше ніж \(k\) букв.
Подивимося, як знаходити найменший рядок з урахуванням обмеження на кількість позицій котрі можна вирізати. Будемо йти зліва направо. Якщо \(s_0 = t_0\), то перший символ покращити не можливо. Інакше, якщо \(s_0 \neq t_0\), то можна знайти в рядку \(s\) букву \(t_0\), вирізати її разом з \(s_0\) та поміняти їх місцями. Таким чином, вирізавши два символи ми дістали кращий рядок. Схожі міркування продовжеємо з наступними буквами по порядку.
В загальному, розглянемо перші \(x\) букв. Порахуємо, скільки букв треба вирізати, для того щоб префікс довжини \(x\) рядка \(s\) співпадав з префіксом рядка \(t\). Усі позиції будуть одного з двох типів, або \(s_i = t_i\), або \(s_i \neq t_i\). В першому випадку нічого вирізати не треба. Проте, всі позиції у яких виконується друга умова треба вирізати, тому що на цих позиціях треба поставити інші символи. Виріжемо всі такі позиції. Нехай їх є \(m\) штук. Тепер, для кожної з них треба знайти в рядку \(s\) букву \(t_i\), вирізати її, і поставити на місце \(s_i\), тобто всього треба вирізати \(m \cdot 2\) символів. Проте, це можна зробити краще. Якщодля якоїсь позиції \(i\) існує \(j < x\), таке що \(s_j \neq t_j\) і \(t_i = s_j\), то на місце \(i\) можемо поставити букву \(s_j\), котру ми і так будемо вирізати. Цим ми економимо одне вирізання.
Загалом, для того щоб порахувати скільки букв треба вирізати для префікса довжини \(x\), для кожного символа \(c\) порахуємо дві величини: \(A_c\) — кількість таких \(i < x\), що \(s_i \neq t_i\) і \(s_i = c\), а також \(B_c\) — кількість таких \(i < x\), що \(s_i \neq t_i\) і \(t_i = c\). \(A_c\) — це кількість символів \(c\), які ми вирізали, а \(B_c\) — кількість позицій, на які символ \(c\) треба поставити. Зрозуміло, що \(min(A_c, B_c)\) символів можемо зразу поставити на своє місце, а \(B_c - min(A_c, B_c)\) треба ще вирізати додатково. Таким чином, загальна кількість символів буде \(m + \sum{B_c - min(A_c, B_c)}\).
Для досягнення лексикографічної мінімальності треба обрати найбільше таке \(x\), що необхідна кількість вирізаних символів не перевишує \(k\). Це можна зробити двійковим пошуком.
Щоб знайти відповідь до задачі, знайдемо оптимальне \(x\). Перші \(x\) символів відповіді співпадатимуть з рядком \(t\). Далі треба знайти які символи треба ще додатково вирізати, і замінити їх на надлишок символів, котрі ми вирізали з префікса. З міркувань лексикографічної мінімальності треба вирізати їх якомога правіше, а вставляти в лексикографічному порядку.
Коректний список доріг у країні має утворювати повне двійкове дерево з висотою \(h\) - 1, а також 3 додаткові ребра, які потрібно знайти. Оскільки кожне з трьох додаткових ребер утворює цикл в дереві, то кандидатами на відповідь можуть бути лише ті ребра, які не є мостами в графі. Знайдемо всі такі ребра. Так як загальна кількість ребер в графі не перевищує 1025, то можна шукати всі мости за \(O(n^2)\) (де \(n\) - кількість вершин в графі), просто видаляючи всі ребра по одному і перевіряючи зв’язність. Отримали множину кандидатів на відповідь.
Оскільки діаметр повного двійкового дерева в не перевищує \(2 \cdot h\), то при додаванні до дерева
одного ребра можна отримати цикл довжиною не більше \(2 \cdot h\). А значить, при додаванні трьох
ребер, загальна кількість ребер в циклах не перевищуватиме \(6 \cdot h\). В обмеженнях задачі \(6 \cdot h \le 60\). Отже якщо множина
кандитатів містить більше як 60 ребер, то це означає що набір доріг
точно не є коректним і відповідь -1
. Інакше переберемо всі
трійки різних ребер з множини кандидатів в лексикографічному порядку,
після чого перевіримо чи після видалення їх з графу в результаті
залишається повне двійкове дерево.
Для перевірки чи граф є повним двійковим деревом можна скористатись наступним критерієм. В графі має бути рівно одна вершина степені 2 — корінь, і рівно \(2^{h - 1}\) вершини степені 1 — листки. Всі інші проміжні вершини мають мати степінь 3. Залишилось перевірити чи граф зв’язний і чи висота дерева рівна \(h - 1\). Для цього можна запустити обхід в глибину починаючи з кореня та підтримувати максимальну глибину серед усіх відвіданих вершин а також їхню кількість.
Отримали алгоритм який працює за \(O(n^2 + n \cdot h^3)\).
Очевидно, що перший алгоритм потрібно завжди реалізувати з нуля. Для всіх інших циклом пройдемо по них (від другого до останнього) та перевіримо, чи відрізняється поточний алгоритм від попереднього. Якщо відрізняється, додамо до відповіді 1.
Серед коржів з однаковим радіусом необхідно вибрати той, що має найбільший об’єм. Коржі з різними радіусами завжди можна поставити так, аби корж зверху мав менший радіус, ніж корж знизу. Отже, потрібно просто просумувати максимальні об’єми по всіх унікальних радіусах.
Один зі способів згенерувати паролі — це розглянути числа від 1 до
\(n\) в системі числення з основою
\(k\). Цифра 0 відповідатиме букві
a
, 1 — b
, і т. д.
Записати число \(x\) в системі числення з основою \(k\) доволі просто — для цього необхідно \(m\) разів виконувати такий процес: візьмемо остачу від ділення \(x\) на \(k\) та цілочисельно поділимо \(x\) на \(k\). Остачі від ділення на кожному кроці утворюють число в системі числення з основою \(k\).
\[\sum_{i=1}^n |p_i - i| \equiv \sum_{i=1}^n p_i + \sum_{i=1}^n i \equiv \frac{n(n+1)}{2}+\frac{n(n+1)}{2} \equiv n(n+1) \equiv 0 \mod 2\]
Отже, якщо \(k\) непарне, то
відповідь NO
.
Якщо \(k \le 2 \cdot (n - 1)\), тоді ми можемо побудувати таку перестановку: \[\left(\underline{\frac{k}{2}+1}, 2, 3, \ldots, \frac{k}{2}-1, \frac{k}{2}, \underline{1}, \frac{k}{2}+2, \frac{k}{2}+3, \ldots, n - 1, n\right)\]
Якщо \(k > 2 \cdot (n-1)\), тоді
зробимо \(p_1 = n\) і \(p_n = 1\). \(|p_1-1|+|p_n-n|=2 \cdot (n-1)\). Зменшимо
\(k\) на \(2
\cdot (n - 1)\) і розв’яжемо меншу задачу на підпослідовності
\((2, 3, \ldots, n - 1)\),
використовуючи аналогічні міркування. Якщо на якомусь кроці ми
використали всі елементи перестановки, але \(k\) все ще більше за 0, значить розв’язку
не існує і відповідь — NO
.
Приклад для \(n=11\), \(k=44\).
\((1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11) \xrightarrow{\text{+20}} (\underline{11}, 2, 3, 4, 5, 6, 7, 8, 9, 10, \underline{1}) \xrightarrow{\text{+16}} (11, \underline{10}, 3, 4, 5, 6, 7, 8, 9, \underline{2}, 1) \xrightarrow{\text{+8}} (11, 10, \underline{7}, 4, 5, 6, \underline{3}, 8, 9, 2, 1)\).
Спробуємо перевірити, чи існує квадрат розміру \(k \times k\) який має усі елементи менші за \(x\).
Утворимо новий масив \(a_{i j} = 0\), якщо \(d_{i j} \le x\) або \(a_{i j} = 1\) інакше. Тоді порахувавши префіксні суми, ми можемо знайти суму в одному квадраті \(k \times k\) за \(O(1)\).
Переберемо всі квадрати, і якщо хоча б в одному з них сума буде рівна \(0\) — це означатиме, що квадрат не містить елементів більших за \(x\).
Тепер ми можемо скористатися методом двійкового пошуку для того, аби знайти мінімальне значення \(x\), для якого існує квадрат \(k \times k\), що містить усі елементи не більші за \(x\). Це значення й буде відповіддю на задачу.
Код розв’язку Python (набирає 10 балів)
Трикутник з найменшою площею побудований на вершинах опуклого многокутника складатиметься з трьох послідовних вершин многокутника. Для доведення цього факту треба скористатись формулою для обчислення площі трикутника: площа рівна половині добутку довжини основи трикутника на довжину висоти, опущеної на неї.
Якщо розглянути трикутник, який складається не з трьох послідовних вершин, зафіксувати дві з них, і сунути третю в один з двох напрямків по вершинах многокутника, довжина висоти буде зменшуватись, а отже площа трикутника також буде зменшуватися. Такий процес можна продовжувати, поки вершини трикутника не будуть послідовними вершинами многокутника. На рисунку площі трикутників \(ABD\) та \(ABE\) менші за площу трикутника \(ABC\), бо відстані від точок \(D\) та \(E\) до прямої \(AB\) менші за відстань від точки \(C\) до цієї прямої.
Тепер подивимось на те, як буде грати Зеник. Оскільки він хоче мінімізувати площу трикутника, то на своєму ході він просто обере найменший трикутник з трьох послідовних вершин многокутника й розріже многокутник уздовж відповідної діагоналі. На цьому гра завершиться.
Марічці ж, знаючи, що Зеник завжди завершить гру своїм ходом, немає змісту давати йому можливість вибрати трикутник з найменшою площею, тому вона на своєму ході обере найбільший трикутник, який складається з трьох послідовних вершин многокутника. Отже, Марічка може завершити гру на першому ході.
Відповідь на задачу — найбільша площа трикутника з трьох послідовних вершин многокутника.
Розглянемо дві сусідні станції \(j\) та \(j+1\). Між ними розташовані будинки з індексами від \(l\) до \(r\).
Сформулюємо та доведемо таке твердження. Для деякого оптимального розв’язку існує такий індекс \(s\), \(l \le s \le r\), що потреби \(i\)-ого будинку будуть повністю забезпечені водою з \(j\)-ої станції при \(l \le i < s\), повністю покриті водою з \((j+1)\)-ої станції при \(s < i \le r\), а потреби \(s\)-ого будинку — частково з \(j\)-ої, частково з \((j+1)\)-ої станцій (можливо, повністю з однієї станції).
Доведення. Припустимо, що до \(i\)-го будинку, де \(l \le i \le r\) привезли воду з \(t\)-ї станції, \(t<j\). Це не вигідно, бо цю воду можна було привезти з \(j\)-ї станції, тоді сумарна відстань буде меншою. Аналогічно невигідно везти воду з \(t\)-ї станції, якщо \(t>j+1\).
Отже, потреби всіх будинків між станціями \(j\) та \(j+1\) вигідно покрити водою із цих станцій.
Нехай \(i_1\) — найправіший будинок, до якого везли воду з \(j\)-ї станції, а \(i_2\) — найлівіший, до якого везли з \((j+1)\)-ї.
Припустимо, що \(i_2<i_1\). Нехай до \(i_1\)-го будинку з \(j\)-ї станції привезли \(c_1\) літрів води, а до \(i_2\)-го з \((j+1)\)-ї — \(c_2\) літрів. Позначимо \(d=\min\{c_1, c_2\}, c_1’=c_1-d, c_2’=c_2-d\).
Якщо до \(i_1\)-го будинку з \(j\)-ї станції привезуть \(c_1’\) літрів води, до \(i_2\)-го з \((j+1)\)-ї станції — \(c_2’\) літрів, а недостачу \(d\) літрів для \(i_1\)-го та \(i_2\)-го будинків будуть покривати відповідно \((j+1)\)-а та \(j\)-а станції, то сумарна відстань зменшиться, позаяк \(c_1’\) або \(c_2’\) дорівнює нулю.
Отже, \(i_1 \le i_2\).
Потреби будинків з номерами меншими за \(i_1\) буде покривати \(j\)-а станція, більшими за \(i_1\) — \((j+1)\)-а станція. Якщо \(i_1=i_2\), то потреби \(i_1\)-го будинку будуть покривати обидві станції. Тому можна взяти \(s=i_1\).
Отже, твердження доведено.
Звідси випливає, що проміжки між сусідніми станціями можна розв’язувати незалежно один від одного. Задача розбивається на підзадачі з двома станціями \(j\) та \(j+1\) та будинками між ними. Навчимося розв’язувати таку підзадачу.
Розв’язок за \(O(\sum_{i} a_i)\).
Скористаємося динамічним програмуванням.
Нехай \(dp_1[x]\) — мінімальна відстань, яку має проїхати автомобіль з лівої станції, щоб відвезти будинкам \(x\) літрів води. \(x\) однозначно визначає, яким будинкам скільки води привезе автомобіль. Нехай \(i\) — найправіший будинок, якому лівий автомобіль привезе воду. Тоді \(dp_1[x] = dp_1[\max\{0, x - k\}]+2(h_i-s_j)\).
Таку саму динаміку \(dp_2\) можна порахувати для правої станції. Відповіддю на підзадачу буде \(\min_x dp_1[x]+dp_2[t-x]\), де \(t=\sum_{i} a_i\) — сума потреб будинків.
Розв’язок за \(O(n^2 \log n)\).
Розглянемо числову пряму, на якій число \(x\) відповідає \(x\) літрам води. \(l\)-му будинкові відповідає півінтервал \(\left(0, a_l \right]\), \((l+1)\)-му — \(\left(a_l, a_l+a_{l+1} \right]\), \((l+2)\)-му — \(\left(a_l+a_{l+1}, a_l+a_{l+1}+a_{l+2} \right]\) і т.д. Позначимо кінець півінтервалу, що відповідає \(i\)-ому будинку \(e_i\). Також у кожного будинку є число \(f_i=2(h_i-s_j)\) — відстань, яку має проїхати автомобіль від \(j\)-ої станції до будинку й назад. Динаміку \(dp_1\) з попереднього розв’язку можна уявити на цій прямій: остання поїздка автомобіля — це стрибок з точки \(x-k\) в точку \(x\), за цей стрибок платимо \(f_i\), де \(i\) — номер будинку, чиєму півінтервалу належить точка \(x\). Процес розвезення води лівим автомобілем можна представити послідовністю точок \(w, w + k, w + 2 \cdot k, \dots, w + p \cdot k\) — за першу поїздку відвозимо \(w \le k\) літрів, за кожну наступну — \(k\) літрів.
Якщо \(w<k\) та жодна з точок \(w+p \cdot k\) не є кінцем півінтервалу якогось будинку, то можемо кожну точку в послідовності посунути вправо на одиницю, при цьому сумарна відстань не збільшиться (кожна точка залишиться в тому півінтервалі, де вона була), а відвезена кількість літрів (остання точка в послідовності) збільшиться на одиницю. Тому варто розглядати тільки такі \(w\), що \(w=k\) або такі, що \(w+p \cdot k=e_i\) для деяких \(p\), \(i\), тобто \(w \equiv e_i \mod k\) — різних кандидатів на \(w\) буде \(O(n)\).
Наступне спостереження: якщо лівий автомобіль привіз повну цистерну води до \(i\)-ого будинку, то він буде продовжувати возити туди повні цистерни, поки може.
Для кожного \(w\) маємо таких кандидатів на межу поділу між лівим та правим автомобілями.
Повністю покриваємо потреби будинків до \((i-1)\)-ого. Воду, що залишилася, веземо до \(i\)-ого будинку. Останньою точкою буде такий мінімальний \(x\), що \(e_{i-1} < x \le e_i\), \(x \equiv w \mod k\). Зауважте, що такої точки може не існувати. Назвемо такого кандидата кандидатом типу А.
Повністю покриваємо потреби будинків до \((i-1)\)-ого. Воду, що залишилася, веземо до \(i\)-ого будинку. Возимо повні цистерни до \(i\)-ого будинку, поки вони туди поміщаються. Останньою точкою буде такий максимальний \(x\), що \(e_{i-1}+k < x \le e_i\), \(x \equiv w \mod k\). Такої точки може не існувати. Назвемо такого кандидата кандидатом типу Б.
Для кожного \(w\) при переході між сусідніми кандидатами легко перераховувати відповідь. Якщо кандидат \(y\) потрапляє в півінтервал \(i\)-ого будинку, а попередній кандидат був \(x\), то до відповіді додасться \(\frac{y-x}{k}f_i\) (число \(\frac{y-x}{k}\) ціле).
Для лівого та правого автомобілів порахуємо відповіді для всіх кандидатів.
Щоб знайти відповідь на задачу, треба для кожного кандидата для лівого автомобіля \(x\) знайти такого найменшого кандидата \(y\) для правого автомобіля, що \(x+y \ge t\), де \(t=\sum_{i} a_i\) — сума потреб будинків.
Це можна зробити, посортувавши кандидатів.
Складність сортування буде \(O(n^2 \log n)\).
Розв’язок за \(O(n^2)\).
Посортуємо всіх кандидатів на \(w\). Зауважимо, що в кожному півінтервалі буде не більше як два кандидати з однаковою остачею за модулем \(k\) (не більше як один типу А та не більше як один типу Б з такою остачею). Хочемо посортувати кандидатів в \(i\)-ому півінтервалі за \(O(n)\). Спершу знайдемо мінімального кандидата типу А в цьому півінтервалі. Нехай його остача за модулем \(k\) дорівнює \(z\). Додамо до посортованого списку кандидатів типу А для всіх остач \(w\) від \(z\) до \(k-1\), потім — від 0 до \(z-1\). Для цього пройдемося по списку кандидатів на \(w\). У такий спосіб ми посортували кандидатів типу А. Так само зробимо з кандидатами типу Б. Отже, посортували всіх кандидатів.
Зауважимо, що ми можемо скористатися бінарним пошуком по відповіді.
Маючи зафіксовану відстань \(x\), потрібно визначити чи можна розфарбувати дерево у щонайбільше \(k\) кольорів так, щоб максимальна відстань між вершинами одного кольору була не більшою за \(x\).
Скористаємося методом динамічного програмування. Вважатимемо, що дерево є підвішеним за довільну вершину. Нехай \(C_i\) — мінімальна кількість кольорів, необхідна щоб розфарбувати піддерево вершини \(i\). Також, нехай \(D_i\) — мінімальна можлива при цьому відстань від вершини \(i\) до вершини такого ж кольору.
Припустимо, що ми хочемо знайти \(C_a\) та \(D_a\) для вершини \(a\), при тому що нам вже відомі значення \((C_{b_1}, D_{b_1}), (C_{b_2}, D_{b_2}), \dotsc , (C_{b_l}, D_{b_l})\) для усіх синів вершини \(a\). Очевидно, що \(C_a \le C_{b_1} + C_{b_2} + \dotsc + C_{b_l} + 1\), адже ми можемо усі піддерева розфарбувати незалежно, а самій вершині \(a\) присвоїти новий колір. Проте, необхідна кількість кольорів може бути меншою, адже можливо деякі кольори можна об’єднати. Впорядкуємо синів вершини \(а\) за зростанням \(D_{b_i}\). Тепер розглянемо деякий префікс цього впорядкованого масиву. Зрозуміло, що якщо ми можемо об’єднати кольори двох останніх синів на цьому префіксі, то можемо приєднати й кольори усіх попередніх синів, адже глибина найглибшої вершини для них є небільшою. Отже, нам потрібно просто знайти найдовший префікс для якого останніх двох синів можна об’єднати. Нехай це префікс довжини \(k\), тоді \(C_a = \sum C_{b_i} - k + 1, D_a = \max D_{b_i}+1\). Зверніть увагу, що випадок, коли жоден з синів вершини \(a\) не може бути одного кольору з вершиною \(a\) (\(min D_{b_i} + 1 > x\)), треба обробити окремо.
Загальна складність — \(O(n \log^2 n).\)
Навчимося ефективно знаходити значення \(f(s, t)\). Розглянемо \(k\)-й префікс рядка \(s\) — \(s_{1..k}\). Знайдемо усі входження цього префікса у рядок \(t\), нехай \(p\) — позиція довільного входження. Зрозуміло, що \(|lcp(s, t_{p..|t|})| \ge k\) і що в позиції \(p\) будуть розпочинатися входження усіх префіксів \(s\) довжиною від 1 до \(|lcp(s, t_{p..|t|})|\). А тому значення функції \(f(s, t)\) є рівним значенню \(\sum_{i = 1}^{|s|} cnt(s_{1..i}, t)\), де \(cnt(x, y)\) — кількість входжень рядка \(x\) у рядок \(y\).
Ефективний спосіб шукати кількість входжень кожного префікса рядка \(s\) у рядку \(t\) є загальновідомим: побудуємо суфіксний автомат по рядку \(t\). Потрібно для кожної вершини автомату знайти розмір множини позицій закінчення входжень, якій відповідає ця вершина. Це робиться динамічним програмуванням по дереву суфіксних посилань автомата. Ми не будемо детально зупинятися на цьому прийомі в межах цього розбору, адже цю інформацію можна знайти в інтернеті.
Нам достатньо побувати суфіксний автомат для рядка \(t\) всього один раз і використати його для обчислення \(f(s_i, t)\) для усіх рядків з набору. Загальна складність розв’язку є лінійною від суми довжин усіх рядків.
Для початку нам потрібно отримати палку довжини 1. Яку палку для цього є зміст використати? Зрозуміло, що нам є зміст укорочувати для цього найкоротшу палку. Аналогічно, палку довжини 3 є зміст робити з найкоротшої палки, довжини щонайменше 3, яка ще не використана для отримання палки довжини 1. Продовжуючи ці міркування, отримуємо повний розв’язок. Впорядкуємо палки в порядку неспадання довжини. Роблячи один прохід по впорядкованому масиву зліва на право, знайдемо спочатку яку палку ми будемо використовувати, щоб отримати довжину 1, яку щоб 3 і так далі. В якийсь момент ми не зможемо знайти палку, щоб отримати чергову необхідну довжину. Остання довжина, для якої ми успішно знайшли палку і є відповідь на задачу.
Складність — \(O(n \log n)\).
Скористаємося методом динамічного програмування. Нехай \(D_k\) — відповідь на задачу, якщо в нас є лише перші \(k\) чисел. Як, знаючи \(D_1, D_2, \dotsc, D_k\), знайти \(D_{k+1}\)? Переберемо, яке буде останнє невидалене число безпосередньо перед \((k+1)\)-шим. Якщо воно є взаємно простим з останнім, то відповідь не зміниться, а в іншому випадку — зросте на одиницю. Тобто, \(D_{k+1} = \max_{i=1}^k (D_{i} + [gcd(a_{k+1}, a_i) \neq 1])\).
Складність такого розв’язку — \(O(n^2 \log(\max a_i))\) — цього недостатньо.
Ведемо словник \(M\), який підтримуватимемо під час обрахунку значень динамічного програмування. Нехай \(p\) — просте число, тоді \(M_p\) — найбільше з вже обчислених значень \(D_i\), таке що \(a_i\) ділиться на \(p\). Тепер перехід динамічного програмування, можна описати так:
\(D_{k+1} = \max(\max_{p\ is\ prime,\ p | a_{k+1}}(M_p + 1), D_k)\).
Зрозуміло, що кількість простих дільників числа \(a_{k+1}\) є логарифмічного порядку, а тому для знаходження нового значення динамічного програмування нам потрібно розглянути щонайбільше логарифм значень зі словника \(M\). Аналогічно, після знаходження нового значення динамічного програмування, нам потрібно оновити щонайбільше логарифм записів у словнику \(M\). Таким чином, якщо вважати що нам відома факторизація усіх чисел, а звернення до елементів словника відбувається з логарифмічною асимптотикою, то сумарна складність становитиме \(O(n \log^2 (\max a_i))\), що є прийнятним для обмежень задачі.
Єдине, що залишилося зробити — факторизувати усі вхідні числа. Факторизувати можна за \(\sqrt{a_i}\), проте можуть виникнути проблеми з часом роботи алгоритму, тому можна використати таку оптимізацію. Скориставшись решетом Ератосфена знайдемо усі прості числа, менші за \(\sqrt{\max a_i}\). Кількість таких простих чисел, що менші за \(k\) можна оцінити як \(O(\frac{k}{\log k})\). Кожне число вхідних даних будемо ділити на кожне з знайдених простих чисел доки це можливо. Якщо після усіх ділень отримане число не рівне одиниці, то ми знайшли єдиний простий дільник, який є більшим за \(\sqrt{\max a_i}\). Таким чином ми знайдемо факторизацію усіх вхідних чисел зі складністю \(O(n \frac{\sqrt{\max a_i}}{\log \max a_i})\).
У задачі просять порахувати кількість пар чисел на проміжку \([l, r]\), що їхнє "побітове і" рівне нулю.
Нехай \(C(x, y)\) — кількість пар чисел \((a, b)\), таких що \(a \le x,\ b \le y,\ a \mbox{ AND } b = 0\). Згідно з принципом включення-виключення, кількість пар чисел \((a, b)\), що відповідають обмеженням \(l \le a \le r,\ l \le b \le r\) рівна \(C(r, r) - C(l-1, r) - C(r, l-1) + C(l-1, l-1)\). У задачі просять знайти такі пари, що \(a \le b\). Зауважимо, що існує лише одна пара з \(a = b\) — \((0, 0)\). При \(a \ne b\) буде враховано пари \((a, b)\) та \((b, a)\), проте для відповіді нам треба порахувати таку пару лиш раз, тому поділимо кількість таких пар на 2.
Щоб знайти \(C(x, y)\) скористаємося методом динамічного програмування. Будуватимемо два числа одночасно ідучи від старших бітів до молодших. Використаємо принцип динамічного програмування, де будуть три стани — кількість вже розглянутих бітів, чи перше число вже є меншим за \(x\) та чи є друге число вже меншим за \(y\). Додаючи новий біт потрібно враховувати, що ми не можемо поставити одиничний біт в обидва числа одночасно, а також не можемо зробити число більшим за його обмеження. Cкладність — \(O(\log r)\).
Знайдемо усі точки перетину многокутників. Оскільки обмеження достатньо малі, то можна це зробити просто перетнувши кожну пару відрізків.
Назвемо координату \(x\) цікавою, якщо існує принаймні одна вершина многокутника чи точка перетину двох відрізків, що має таку координату по осі абсцис.
Розглянемо незалежно кожну вертикальну смужку між послідовними цікавими координатами. Знайдемо усі ребра многокутників, що проходять через цю смужку й впорядкуємо їх у порядку зростання ординати точки, що належить цьому ребру і має значення абсцис-координати рівне середині смужки, що розглядається. Розглядаючи ребра в такому порядку, ми можемо підтримувати кількість многокутників, що покривають трапецію, яка зараз розглядається. Кожне ребро або збільшує цю кількість на одиницю, або зменшує. Це можна однозначно визначити за орієнтацією ребра, так як усі многокутники задані в порядку обходу проти годинникової стрілки.
Нехай \(s\) — довільний рядок з нулів і одиниць. Нехай \(F(s)\) — масив чисел, такий, що перше його число рівне кількості однакових символів на початку рядка \(s\), друге число — кількості однакових символів в другій групі і так далі. Наприклад, \(F("0001101") = [3, 2, 1, 1]\), а \(F("111") = [3]\).
Аналізуючи описані операції, можна зрозуміти, які умови є необхідними й достатніми, щоб з рядку \(s\) можна було отримати рядок \(t\):
Перші символи рядків мають бути рівними.
Довжини масивів \(F(s)\) та \(F(t)\) мають бути однаковими, адже ми ніяк не можемо змінити кількість груп однакових символів в рядку.
Розміри перших груп обох стрічок мають бути рівними: \(F(s)_1 = F(t)_1\).
Аналогічно, розміри останніх груп мають бути рівними: \(F(s)_{|F(s)|} = F(t)_{|F(t)|}\).
\(F(s)_i \ge F(t)_i\) для всіх \(i\), адже ми не можемо добавляти нових символів.
\(F(s)_i \equiv F(t)_i\ (mod\ 2\)) для \(i=2..|F(s)|-1\), адже обидві операції не змінюють парність розміру кожної групи.
Очевидно, що функції \(F\) і усі необхідні перевірки можна реалізувати з лінійною складністю.
Виконаємо перші \(m\) кроків і будемо перевіряти, чи Зеник не вийшов за межі многокутника і якщо таке відбулося, то ми знайшли відповідь. Нехай \(P_i\) — позиція Зеника після виконаних \(i\) кроків, де \(i = 0..m\). Після \(j = k \cdot m + r\) кроків ми опинимось у точці \(k \cdot \overrightarrow{P_m} + \overrightarrow{P_r}\).
Якщо \(|\overrightarrow{P_m}| = 0\),
Зеник буде циклічно ходити по тих самих точках і відповідь —
-1
. У випадку \(|\overrightarrow{P_m}| > 0\), то після
кожних \(m\) ітерацій Зеник буде
зміщуватися на вектор \(\overrightarrow{P_m}\), і, рано чи пізно,
вийде за межі сногокутника.
Розглянемо остачу \(r\) за модулем \(m\) і подивимось на позиції Зеника після ходів з індексами \(k \cdot m + r\). Якщо розглянути збільшення \(k\) від 0 до нескінченності, то спочатку відповідні точки знаходяться всередині многокутника, а після певного моменту — ззовні. Тому можна скористатися двійковим пошуком по \(k\), щоб знайти першу точку з остачею \(r\), яка знаходиться зовні многокутника. Знайдемо всі такі точки для кожної остачі \(r\) від 0 до \(m-1\). Відповідь буде індекс найменшої з них.
Для розв’язку задачі необхідно навчитися швидко перевіряти, чи належить точка многокутнику.
Перевірити, чи точка \(B\) належить опуклому многокутнику, можна за логарифмічну складність:
Знайдемо найлівішу точку многокутника, якщо таких декілька, то найнижчу, назвемо її \(A\).
Інші вершини многокутника будуть посортовані за полярним кутом відносно точки \(A\).
Для заданої точки \(B\) бінарним пошуком за полярним кутом можемо знайти дві сусідні вершини многокутника \(L\) та \(R\), такі що полярний кут точки \(B\) відносно точки \(A\) лежить між полярними кутами \(L\) і \(R\).
Перевіримо, чи точка \(B\) лежить всередині трикутника \(ALR\).
Отож, вибравши мінімальну відповідь серед усіх остач \(r\) ми отримуємо повний розв’язок з асимптотичною складністю \(O(m \log{n} \log({max\_coord}))\).
Цей розв’язок можна оптимізувати, забравши з асимптотики один з логарифмів. Залишаємо це покращення для читачів вправою на домашнє завдання.
I. Дерево мінімальної глибини.
Побудуємо незважений орієнтований граф з \(n\) вершин. Ребро \((a, b)\) існує в графі, якщо виконується хоч одна з двох умов:
\(a\) є батьком вершини \(b\) у початковому дереві.
Серед дозволених операцій є операція \((a, b)\).
Нехай \(D_i\) — найкоротша відстань від вершини 1 до вершини \(i\) у вищеописаному графі. Максимальне з усіх значень \(D_i\) і є відповіддю на задачу. Усі \(D_i\) можна знайти за допомогою пошуку в ширину з лінійною складністю.
Важливо, що кожна операція змінює усі елементи масиву, а не лише елементи на обраному відрізку. Зрозуміло, що нам вигідно на кожному кроці обирати відрізок з найбільшим середнім значенням. Виникають два запитання:
Скільки кроків потрібно зробити?
Легко показати, що максимальний елемент масиву зменшуватиметься щонайменше на половину на кожному кроці (так як ми точно можемо знайти відрізок з середнім як мінімум \(\frac{\max a_i}{2}\)). А тому кількість кроків обмежена логарифмічним порядком.
Як ефективно шукати відрізок з найбільшим середнім значенням?
Покажемо, що оптимальний відрізок має довжину 2 або 3. Розглянемо довільний відрізок довжини не менше 4. Нехай його середнє арифметичне рівне \(x\). Глянемо на середнє арифметичне перших двох елементів цього відрізка. Якщо воно є більшим чи рівним за \(x\), то ми знайшли менший відрізок, довжини два, який має не гірше значення. Якщо ж середнє арифметичне перших двох елементів є строго меншим за \(x\), то середнє арифметичне решти елементів має бути більшим за \(x\). Цей факт легко довести самостійно, а тому ми опустимо деталі в цьому розборі. Таким чином, ми показали що для будь-якого відрізка дожини щонайменше 4, можна знайти коротший відрізок з не меншим середнім значенням. Тому, щоб знайти оптимальний відрізок досить перевірити лише усі відрізки довжини два та три.
.
Сумарна складність розв’язку — \(O(n \log(\max a_i))\).
Нехай \(f(a, b)\) — індекс першого біта (в порядку від старших бітів до молодших), в якому число \(a\) відрізняється від числа \(b\). Вважатимемо, що \(f(a, a) = -1\). Також, нехай \(a[i]\) — це значення \(i\)-го біту числа \(a\) (0 або 1).
Нехай \(C_{l, x, r, y}\) — кількість таких \(i\) від 2 до \(n - 1\), що \(f(a_{i-1}, a_i) = l, f(a_i, a_{i+1}) = r, a_i[l] = x\) та \(a_i[r] = y\) у початковому масиві. Усі такі значення легко обчислити з складністю \(O(n \log \max a_i)\).
Зауважимо, що кількість локальних максимумів до виконання запитів є рівною \(\sum_{i=1}^m \sum_{j=1}^m C_{i, 1, j, 1}\), де \(m\) — кількість бітів у найбільшому числі з вхідних даних.
Після виконання операції xor
, номер першого біта в якому
відрізняються сусідні числа не змінюється, а змінюються лише значення
цих бітів. Зокрема, не важко зрозуміти, що якщо ми виконуємо \(xor\ x\) для всіх елементів масиву
початкового масиву, то кількість локальних максимумів становитиме \(\sum_{i=1}^m \sum_{j=1}^m C_{i, x[i] \oplus 1, j,
x[j] \oplus 1}\). Цей факт дає повний розв’язок з складністю
\(O(n \log(\max a_i))\).
Ціна однієї канапки \(price = a + 2 \cdot b + c\). Отже відповідь до задачі це \(\lfloor \frac{s}{price} \rfloor\) (ділення націло).
Об’єм води за годину в Дністрі після \(i\)-того села — це сума об’єму води за
годину яка була в Дністрі до \(i\)-того
села та у всіх струмках які втікають безпосередньо перед \(i\)-тим селом. Таку суму потрібно
порахувати для кожного села. Зауважте, що об’єм води може перевищувати
розмір 32-бітного типу даних (для прикладу, int
в C++),
тому для суми тут потрібно використовувати 64-бітний тип даних
(long long
в С++).
Зауважимо, що рядок kanapka
починається та закінчується
на підрядок ka
. Щоб отримати два входження рядка
kanapka
оптимально буде накласти початок другого входження
на кінець першого, отримавши рядок kanapkanapka
. Щоб
отримати третє входження можна просто додати рядок napka
і
отримати kanapkanapkanapka
.
Формалізуємо алгоритм:
утворюємо один рядок
ka
,поки можемо, дописуємо рядки
napka
до кінця рядка.
Позначимо кількість символів k
, a
,
n
та p
— \(cntK\), \(cntA\), \(cntN\) та \(cntP\) відповідно.
Тоді максимальна кількість входжень буде рівна \(\min (cntK-1, \lfloor \frac{cntA - 1}{2} \rfloor,
cntN, cntP)\) якщо є хоча б по одному входженню букв
k
та a
.
Якщо ж в рядку немає букви k
чи букви a
, то
відповідь на задачу 0.
Очевидно, що Зенику варто піти або в супермаркет, або відвідати магазин кожного типу окремо, оскільки якщо Зеник відвідав супермаркет, то йому вже не потрібно йти ще в якийсь магазин. Отже задача зводиться до двох випадків: коли Зеник йде в супермаркет, або коли Зеник купує продукти у всіх магазинах окремо.
Розгляньмо випадок, коли Зеник йде до супермаркету. Оскільки ми хочемо мінімізувати відстань до координати 0, то варто вибрати супермаркет який найближчий до цієї координати. Тому нам потрібно вибрати такий супермаркет, в якого мінімальне значення \(|d_i|\). Це можна зробити за \(O(n)\).
Тепер розгляньмо випадок коли Зеник купує всі продукти в різних магазинах. Як порахувати відповідь коли ми маємо лише по одному магазину кожного типу? Знайдімо найправішу координату і найлівішу. Позначимо координати хлібного, м’ясного та сирного магазинів як \(a\), \(b\) та \(c\) відповідно. Легко зрозуміти що координата найлівішої точки це \(l = \min (a, b, c, 0)\), а найправішої \(r = \max (0, a, b, c)\). Щоб оптимально обійти їх нам потрібно спочатку піти в один бік, повернутися додому, піти в інший бік і знову повернутися додому. Отже відповідь для випадку магазинів різних типів буде \((|l| + r) \cdot 2\).
Що робити якщо магазинів багато? Ми можемо перебрати магазин кожного типу в який піде Зеник і таким чином знайти відповідь. Такий алгоритм праюватиме за \(O(n^3)\), що занадто повільно. Цей алгоритм легко оптимізувати.
Розглянемо магазини одного типу. Якщо є якісь два магазини з додатніми координатами, то нам ніколи не буде вигідно йти до магазину який знаходиться далі від нас, тому його не потрбіно перебирати. Аналогічні міркування справджуються і для магазинів з від’ємними координатами. В результаті, для кожного типу магазинів нас цікавлять лише два магазини: найближчий до нас з додатньою координатою і найближчий з від’ємною координатою. Після того як ми викинемо решту магазинів, всього їх залишиться не більше ніж 6: по 2 кожного типу. Тепер для кожного типу магазинів можемо перебрати до якого підемо, тому що різних таких комбінацій буде не більше ніж \(2 \cdot 2 \cdot 2 = 2^3 = 8\).
Відповідь на задачу це мінімум з двох випадків: або йдемо до найближчого супермаркета, або до кожного типу магазинів окремо.
Загальна складність алгоритму \(O(n + 2^3)\).
Зеник спочатку задонатив \(b\) гривень, а потім \(k\) разів по \(x\) гривень. Тобто, можна записати це формулою \(b + k \cdot x\). Отже, в задачі було достатньо запрограмувати таку формулу.
Як альтернативний розв’язок можна було \(k\) разів додати \(x\) до відповіді за допомогою циклу.
В даній задачі потрібно було перевірити чи 47
є в числі.
Для зручності можна зчитати це число як рядок. Тепер нам потрібно
перевірити входження підрядка 47
в нього, що можна зробити
циклом або вбудованими функціями мови програмування. Також цю перевірку
можна було зробити без використання рядків.
Спочатку навчимось перевіряти чи Петро зможе дійти до зупинки не пізніше ніж до неї приїде трамвай. Для обрахунку часу потрібно поділити відстань на швидкість. Використовуючи цю формулу знайдемо витрачений час трамваю та час Петра. З обмежень задачі можна помітити, що отримані часи будуть цілими. Отже для точності розв’язку будемо обраховувати їх діленням націло.
Для кожної зупинки ми дізнаємось чи Петро може до неї дійти і встигнути на трамвай. Якщо він зможе дійти до двох зупинок, тоді необхідно додатково перевірити до якої зупинки йому ближче. Він піде до першої зупинки, якщо до неї відстань не більша ніж до другої. У випадку якщо він зможе дійти лише до однієї зупинки, то нам потрібно визначити до якої саме. Якщо ж не може дійти до жодної тоді він не встигне на тренування.
Порахуємо кількість різних PIN-кодів. Ми знаємо що кожну цифру можна вибирати двома способами. Також обираємо їх незалежно одну від одної. Тому відповідь це добуток кількості варіантів для кожної з цифр, що в даному випадку дорівнює \(2^n\).
Якщо перебрати усі можливі пари PIN-кодів і виконати для них відповідну операцію, то необхідно порахувати скільки раз ми отримали рядок \(x\). Такий розв’язок пройде приклади та перший блок тестів.
Якщо ми переберемо тільки перший PIN-код, то, згідно умови, можемо однозначно знайти другий. Це можна зробити таким чином: якщо в рядку \(x\) на \(i\)-тій позиції цифра 0, то в другому PIN-коді ставимо таку ж цифру як і в першому. Якщо ж на \(i\)-тій позиції 1, то змінимо цифру з першого PIN-коду на протилежну. Отже, ми можемо згенерувати всі PIN-коди довжини \(n\) і кожен з них буде першим PIN-кодом рівно в одній парі, що нам підходить. Такий розв’язок пройде другий блок тестів.
Оскільки кожен PIN-код утворить одну пару, що нам підходить, а кількість PIN-кодів \(2^n\), то й відповідь до задачі \(2^n\).
Тому для повного розв’язку задачі достатньо вивести \(2^n\).
Перший блок тестів можна розвязувати такими способами:
Для кожного дня порахуємо кількість регіонів з міст під контролем 47-ляндії. Для цього будемо ітеруватись по містах. Якщо ми зустрічаємо місто під контролем 47-ляндії, яке ми ще не відвідували, то обійдемо усі досяжні з нього міста підконтрольні 47-ляндії. Тепер усі ці міста є відвіданими і більше цей регіон не буде врахований. Таким чином після кожного дня ми можемо порахувати відповідь. Складність такого алгоритму буде рівна \(O(q \cdot n)\).
Для кожного міста, будемо пам’ятати значення \(cnt_v\) — скільки в неї є сусідініх міст під контролем 47-ляндії. Тоді коли місто перестає бути підконтрольним 47-ляндії то замість одного регіону, ми отримуємо \(cnt_v\) регіонів. Кожне сусіднє місто буде в своєму окремому регіоні. І навпаки якщо місто стає підконтрольним 47-ляндії, то \(cnt_v\) регіонів об’єднаються в один. При зміні стану міста оновимо значення \(cnt\) для кожного сусіднього міста. Такий розв’язок має складність рівну \(O(q \cdot n)\).
Розглянемо країну як структуру дерево. Візьмемо одне з міст як корінь цього дерева, кожна вершина в цьому дереві, крім кореня, має батька. Тепер замість \(cnt_v\), пам’ятатимемо \(son_v\) — кількість синів даної вершини під контролем 47-ляндії. Для того аби визначити \(cnt_v\) нам достатньо перевірити чи батько даної вершини належить 47-ляндії. А решта сусідніх міст є синами поточної вершини, ми знаємо скільки серед них належать 47-ляднії — \(son_v\). У випадку коли батько належить 47-ляндії, тоді \(cnt_v = son_v + 1\), у іншому варіанті \(cnt_v = son_v\). Тепер якщо вершина змінює свій стан тоді ми маємо оновити значення \(son\) для її батька, якщо звісно він існує. Тоді кожна така операція працює за \(O(1)\), а сумарна складність запитів рівна \(O(q)\). Також необхідно порахувати початкові значення \(son_v\), що ми можемо зробити за \(O(n)\) звичайним пошуком вглиб, або певними формулами.
Код розв’язку C++ \(O(n \cdot q)\)
Код розв’язку C++ \(O(n \cdot q)\)
Переберемо всі підрядки рядка \(s\). Для кожного такого підрядка переберемо всі підрядки \(t\) і порівняємо їх на рівність. Такий розв’язок працюватиме за \(O(|s|^2 \cdot |t|^2 \cdot cmp)\), де cmp — час порівняння двох підрядків, що в найгіршому випадку рівне \(O(|t|)\). Цей розв’язок пройде перший блок тестів.
Розглянемо швидший розв’язок. Переберемо всі підрядки рядка \(t\) і запишемо їх в мультимножину. Тепер для кожного підрядка \(s\), замість того щоб перебирати підрядок в \(t\), просто подивимося скільки таких підрядків є в нашій мультимножині. Такий розв’язок працюватиме за \(O((|t|^2 + |s|^2) \cdot log(|t|^2) \cdot cmp)\), де cmp — час порівняння двох підрядків, що в найгіршому випадку рівне \(O(|t|)\). Цей розв’язок пройде два перші блоки тестів.
Тепер розглянемо розв’язок, який розв’яже задачу з повними обмеженнями. Нехай ми знайшли підрядки з рядків \(s\) та \(t\) які співпадають. Очевидно, що всі їхні відповідні рядки також співпадають. Якщо довжина підрядків які співпадають рівна \(n\), то можна до відповіді додати \(\frac{n \cdot (n + 1)}{2}\) і вже не розглядати їх підрядки. Тоді якщо ми співставимо \(s\) і \(t\) у всіх можливих позиціях і знайдемо проміжки де рядки співпадають, то зможемо легко порахувати відповідь.
Наприклад якщо \(s\) = aabcabb, а \(t\) = abba, то один з варіантів співставлення виглядатиме так:
Тут є підрядки довжин 2 та 1, тому до відповіді треба додати \(\frac{2 \cdot 3}{2} + \frac{1 \cdot 2}{2} = 3 + 1 = 4\). Зауважимо, що рядок \(t\) може виходити за межі \(s\), наприклад так:
Оскільки в нас є \(|s| + |t| - 1\) позиція для того щоб їх співставити, то загальна складність такого алгоритму буде \(O((|s| + |t|) \cdot |t|)\).
Розглянемо перший блок тестів, у ньому нам потрібно заповнити прямокутник розміру \(1 \times (n - b[i])\), тому навчимось розвязувати задачу заповнення коли в нас є прямокутник розміру \(1 \times m\). Для цього розглянемо найправішу плиточку, що буде стояти в цьому прямокутнику. Вона може бути розміру 1 або розміру 2. Поставивши одну з цих плиточок в нас залишиться прямокутник розміру \(1 \times (m - 1)\) або \(1 \times (m - 2)\) відповідно. Визначимо \(f[m]\), як відповідь на задачу для прямокутника розміру \(1 \times m\). Тоді можна записати таке рівняння: \(f[m] = f[m - 1] + f[m - 2]\), а значення \(f[0]\) і \(f[1]\) рівні 1. Цей масив можна обрахувати звичайним циклом.
Перейдемо до другого блоку, нам потрібно заповнити прямокутник розміру \(2 \times (n - a[i])\), тобто потрібно вміти розвязувати задачу заповнення для прямокутника \(2 \times m\). Для цього введемо два масиви \(g[m]\) — відповідь на задачу для прямокутника розміру \(2 \times m\), та допоміжний \(h[m]\) — відповідь на задачу для фігури зображеної нижче, зрозуміло що відповідь буде аналогічна якщо зверху буде більша кількість вільних клітинок.
Спробуємо для них написати рівняння подібно до першого блоку, для цього розглянемо як зліва будуть замощені плиточки , спочатку для \(h[m]\). Для цієї фігури є два варіанти яка плиточка знаходиться в найлівішій вільній клітинці:
Якщо ставимо плитку розміру 1, то переходимо до задачі \(g[m - 1]\), якщо ж розміру 2 то до задачі \(h[m - 1]\), тому формула \(h[m] = g[m - 1] + h[m - 1]\). Тепер розглянемо задачу \(g[m]\).
Тепер розглянемо усі можливі варіанти плиточки що буду покривати ліву нижню клітинку:
У перших двох варіантах ми переходимо до задач \(h[m]\) і \(g[m - 1]\) відповідно. Для третього варіанту:
Розглянемо варіанти плиточки для лівої верхньої клітинки.
Тобто переходимо до задач \(h[m - 1]\) і \(g[m - 2]\) відповідно. А отже кінцева формула буде такою: \(g[m] = h[m] + g[m - 1] + h[m - 1] + g[m - 2]\). Отже ми можемо ці відповіді порахувати в циклі, спочатку рахуємо \(h[m]\) потім \(g[m]\).
Зауважимо що \(g[1]\) рівне 2, бо ми можемо взяти дві плиточки розміру 1 або одну розміру 2. А \(g[0]\) рівне 1, бо ми нічого не ставимо, як і було сказано в примітках. Значення \(h[1]\) буде рівне 1, бо ми можемо поставити лише одну пличотку. Зрозуміло, що \(h[0] = 0\), бо такої фігури не існує, а отже її не можна заставити плиточками.
Повернемось до початкової задачі. Без обмежень загальності, нехай у верхньому рядку потрібно закласти \(m\) клітинок, а у нижньому на \(d\) більше.
Тепер розглянемо межу між прямокутником ширини 1 і прямокутником ширини 2. Розглянемо варіант коли там стоїть плиточка розміру 2.
У такому варіанті зліва в нас задача \(f[d - 1]\), а справа \(h[m]\) і ці задачі незалежні, тобто для кожного способу зліва можна вибрати будь-який спосіб справа, тому кількість варіантів рівна добутку цих двох величин. Зауважимо, що цей варіант можливий лише за умови \(d \geq 1\) і \(m \geq 1\), для того аби плиточка розміру два мала клітинки на які її ставитимуть.
Якщо ж на межі не було плиточки довжини 2, то в нас будуть дві незалежні задачі, одна виділена синім, а інша жовтим.
Тоді відповідно в нас є задача \(f[d]\) і \(g[m]\), аналогічно до попереднього варіанту до відповіді потрібно додати добуток цих величин. Отже, відповідь на задачу буде рівна \(g[m] \cdot f[d] + h[m] \cdot f[d - 1]\).
У даній задачі необхідно знайти за скільки днів закінчаться солдати в кожній ворожій країні. І взяти максимум з цих значень, тобто \(max(\frac{A}{C}, \frac{B}{D})\). Врахуйте те що результат є цілим числом і тому можна використовувати цілочисельне ділення.
Якщо ми порахуємо суму втрат за \(n - 1\) день, тоді різниця загальних втрат і цієї суми буде рівна кількості втрат в загублений день. Зауважте, що якщо отримане число не є додатнім, тоді Зеник допустив десь помилку.
Враховуючи умову про те що вантажівка може за один раз доставляти
незвичні матеріали лише в один рядок, нам необхідно для кожного рядка
порахувати мінімальну кількість поїздок аби розставити потрібні
матеріали. У кінці отримані значення для рядків необхідно буде
просумувати. Зауважимо, що для рядка нам не важливо де знаходяться
«*
», а цікавить лише їх кількість — \(cnt\). Тоді будемо жадібно возити
матеріали, веземо повну вантажівку з \(k\) одиницями матеріалу, або ту кількість
що залишилась. Також цю кількість можна було порахувати формулою \(\lceil\frac{cnt}{k}\rceil\), цю формулу
можна рахувати використавши цілочисельне ділення в формулі \(\lfloor\frac{cnt + k - 1}{k}\rfloor\).
Для того аби отримати хоча б 10 балів було достатньо відтворити процес вказаний в умові, тобто ітеруємось по масиву, щоб знайти сусідні клітинки з найбільшою різницею і поміняємо місцями їх значення. Цей процес будемо робити поки масив не стане посортованим. Проте такий розв’язок є доволі повільним. Тому необхідно зауважити, що якщо є два елементи \(i\) та \(j\) для яких виконується \(i < j\) та \(a_i > a_j\), тоді колись ми їх поміняємо місцями. А пару елементів для якої виконується \(i < j\) та \(a_i < a_j\) ми ніколи не будемо міняти місцями. Отже, задача зводиться до того аби порахувати кількість інверсій, тобто кількість таких пар \(i < j\), що \(a_i > a_j\). І це можна зробити використавши два вкладені цикли по \(i\) та по \(j\).
Перш за все впорядкуємо військові об’єкти за відстанню від початку колони. Оскільки об’єкти не рухаються, то нема змісту обстрілювати одну ділянку більше одного разу.
Використаємо підхід динамічного програмування. Будемо знищувати об’єкти зліва направо. Стан буде характеризуватися кількістю знищених військових об’єктів від початку колони \(cnt\). Також, враховуючи те що в нас є обмеження на кількість пострілів з хаймарсу, це теж необхідно вказати в стані динаміки. А отже наша динаміка виглядатиме так: \(dp[cnt][himars]\) — мінімальна кількість пострілів, щоб знищити перші \(cnt\) об’єктів зробивши при цьому рівно \(himars\) пострілів з хаймарсу. Тоді, для того аби перерахувати цю динаміку, будемо вважати що останній зроблений постріл має правий кінець рівно в позиції \(cnt\)-го об’єкту. Усі об’єкти з координатою в проміжку \([a_{cnt} - x, a_{cnt}]\) будуть знищені з граду і \([a_{cnt} - y, a_{cnt}]\) з хаймарсу. А отже нам потрібно для кожного варіанту пострілу знайти найлівіший об’єкт який буде обстріляний цим пострілом. Це можна зробити двійковим пошуком, або методом двох вказівників, оскільки це не залежить від змінної \(himars\). Тоді ми знаємо скільки зліва залишиться об’єктів, також нам відомо для них значення динаміки, тобто найменшу кількість пострілів щоб знищити цей префікс. Зрозуміло, що постріл з хаймарсу можна зробити лише якщо \(himars > 0\) і тоді значення динаміки буде мінімумом з двох варіантів пострілу.
Для того аби знайти відповідь на задачу потрібно перебрати \(himars\) — яку кількість пострілів з хаймарсу ми зробимо. Відповідь буде рівна мінімуму серед значень динаміки \(dp[n][himars]\).
Використаємо алгоритм Дейкстри. Для кожного міста \(v\) будемо підтримувати \(D[v]\) — поточний мінімальний час за який туди можна потрапити з першої вершини. Початково значення \(D[v]\) встановимо достатньо великим числом.
Візьмемо місто, серед ще не розглянутих, з найменшим часом. Спробуємо через дане місто доїхати до сусідніх міст, які з’єднані прямою дорогою \(e\) з даним містом. Порахуємо найменший момент часу у який ми зможемо доїхати до сусіднього міста по даній дорозі. Для цього подивимось коли ми зможемо поїхати по даній дорозі і не потрапити під обстріл. Оскільки обстріли зациклені, то ситуація на цій дорозі в момент часу \(D[v]\) така ж як і в момент часу \(t = D[v] \mod (c[e] + d[e])\), де \(\mod\) рахує остачу від ділення. Якщо зараз дорога обстрілюється (\(t < c[e]\)), то ми повинні зачекати до перезарядки і почати рух в той момент коливона почнеться. Якщо ж дорога не обстрілюється (\(c[e] \le t\)), то нам необхідно перевірити чи ми встигнемо доїхати до початку нового обстрілу (\(t + l[e] \le c[e] + d[e]\)). Якщо встигаємо то просто їдемо і доїжджаємо в момент часу \(D[v] + l[e]\), інакше необхідно чекати коли наступний обстріл закінчиться і тоді їхати. Зауважимо, що якщо для того аби проїхати по дорозі нам необхідно більше часу ніж час перезаряджання, тоді ми ніколи не зможемо по цій дорозі проїхати. Цей процес будемо продовжувати поки у нас залишаються ще нерозглянуті міста.
Зауважимо, що нам цікаво лише які клітинки, з мінами і журналістами, ми відвідували і в якій клітинці ми зараз стоїмо. Використаємо підхід динамічного програмування. Будемо підтримувати бітмаску розміру \(2 \cdot k\) для тих клітинок які вже відвідані, а також в якій клітинці з \(2 \cdot k\) цікавих ми стоїмо. Значення динаміки \(dp[mask][v]\) — найкоротша відстань щоб пройти від стартової клітинки по відвіданих клітинках в \(mask\) і остання клітинка в якій ми зупинимось буде \(v\). Для обрахунку цієї динаміки переберемо з якої клітинки ми прийшли і серед усіх варіантів знайдемо мінімум. Зауважимо, що стан з якого ми прийшли буде містити на 1 біт менше у своїй бітмасці, і буде мати значення бітмаски менше. Тому якщо ми перебиратимемо маски по зрозстанню, то для обрахунку поточного значення будемо використовувати вже обраховані значення динаміки.
Проте ми не враховували, що пес Патрон початково не знаходиться в жодній з цікавих клітинок, тому значення динаміки для станів з однією знешкодженою міною буде рівне відстані що пройде пес Патрон від своєї початкової клітинки до цієї міни. У кінці нам потрібно буде лише перебрати останню клітинку в якій ми зупинемось, а бітмаска буде містити усі біти. Серед таких станів нам потрібно знайти найменше значення динаміки.
Зауважимо, що для пришвидшення цієї динаміки можна пропускати недосяжні стани, наприклад, якщо пес Патрон відвідав більше журналістів ніж мін.
Зеник з \(i\)-ої гвинтівки може вистрілити \(\lfloor \frac{x}{b_i} \rfloor + 1\) разів. Тому нам необхідно помножити це число на \(a_i\), щоб порахувати шкоду, що може нанести \(i\)-а гвинтівка. Отже, в задачі необхідно знайти гвинтівку з найбільшим таким значенням.
Для того аби знищити \(i\)-тий
ворожий літак Зенику необхідно нанести \(\lceil \frac{h_i}{a} \rceil\) ударів. І щоб
Зеника не підбили його літак повинен витримати вистріли у відповідь,
таких вистрілів буде \(\lceil \frac{h_i}{a}
\rceil - 1\). А сумарна шкода літаку Зеника за цей двобій буде
рівна \((\lceil \frac{h_i}{a} \rceil - 1)
\cdot d_i\). Отже, будемо пам’ятати скільки міцності в літака
Зеника ще залишилось і будемо віднімати сумарну шкоду. Якщо після
якогось повітряного бою в нього вийшла міцність менша або рівна за 0,
тоді літак Зеника не зможе вціліти і відповідь тоді No
. А
якщо ж такого не сталось, то його літак цілий і у відповідь необхідно
вивести Yes
.
Використаємо жадібний підхід. Для взводів, що мають однакову найменшу кількість людей, дамо по одному ящику з боєприпасами. Для взводів з другим найменшим значенням дамо по 2 ящики з боєприпасами і так далі. Тобто впорядкуємо взводи за кількістю людей в них. Перший з них отримає 1 ящик з боєприпасами. Далі ітеруємось по взводах від другого, якщо в даного взводу така ж кількість людей як в попереднього то дамо йому стільки ж якщиків як і попередньому взводу. Інакше необхідно дати на 1 ящик більше.
Зауважте, що відповідь може бути більшою за \(5 \cdot 10^9\), а отже необхідно використовувати тип даних, що дозволяє працювати з такими великими значеннями.
У нас є два варіанти в яку сторону буде відправлена посилка: вліво або вправо. Розглянемо випадок, коли посилка буде відправлена вправо (\(a_i < b_i\)). Інший варіант буде аналогічно розв’язуватись. Отже, для того аби доставити таку посилку ми маємо спочатку відвідати позицію \(a_i\), а потім \(b_i\). Припустимо, що ми можемо доставити певним чином посилку, тоді розглянемо останній раз коли ми були в клітинці \(a_i\) перед тим як доставити посилку. Ми повинні іти вправо з цієї клітинки, тобто мала існувати така ключова позиція \(x_j\), що існує наступна позиція \(x_{j+1}\) і виконується нерівність \(x_j \le a_i < x_{j+1}\). Аналогічно зробимо для \(b_i\), але ми розглянемо перше відвідування \(b_i\) після того як взяли посилку в \(a_i\). Тоді ми мали прийти в позицію \(b_i\) зліва, тобто має існувати такий момент \(x_k\) для якого існує \(x_{k-1}\) і виконується нерівність \(x_{k-1} < b_i \le x_k\). Отже, якщо існують два таких індекси \(j\) та \(k\) для яких виконується \(x_j \le a_i\), \(b_i \le x_k\) та \(j < k\) — умови того, що ми з \(a_i\) підемо вправо, в \(b_i\) прийдемо зліва і відповідно що посилку ми візьмемо швидше ніж доставимо її. Якщо таких індексів не існує, то ми не зможемо доставити посилку. У випадку якщо \(b_i < a_i\) нам потрібно знайти індекси \(j\) та \(k\) для яких виконуються умови \(a_i \le x_j\), \(x_k \le b_i\) та \(j < k\).
Для того аби перевірити чи існують потрібні індекси знайдемо найменше \(j\) для якого буде виконуватись умова між \(a_i\) та \(x_j\) (\(x_j \le a_i\) або \(a_i \le x_j\)). Аналогічно знайдемо найбільше \(k\) для якого буде виконуватись умова між \(b_i\) та \(x_k\) (\(b_i \le x_k\) або \(x_k \le b_i\)). Якщо відповідні індекси існують і для них виконується \(j < k\), тоді посилку можна доставити. Отже, такий розв’язок буде працювати за \(O(m \cdot n)\), бо для кожної посилки нам потрібно перебрати індекс ключової позиції.
Для пришвидшення попереднього розв’язку посортуємо \(n\) пар (\(x_{ind}\), \(ind\)), тоді кожна умова буде виконуватись для певного префіксу або суфіксу цього масиву. Оскільки нам потрібно мінімум і максимум, то створимо масив в якому будемо пам’ятати, на кожному префіксі та кожному суфіксі, мінімальне та максимальне значення другого параметру з пари. А визначати для якого префіксу або суфіксу виконується умова, можна за допомогою двійкового пошуку.
Для зручності відсортуємо вантажівки по їх координаті.
Для того аби отримати бали за два найлегших блоки необхідно було перебрати вантажівку в яку ми вистрілимо і відтворити процес вибухів. Наприклад, для цього можна підтримувати проміжок \([l, r]\), де усі вантажівки в цьому проміжку вибухнуть. Проте на цьому проміжку могли бути вантажівки які ми ще не розглянули, такі вантажівки можуть оновити значення \(l\) і \(r\). У простішому блоці можна було проітеруватись по усіх вантажівках і подивитись чи вони в проміжку і ми їх ще не розглнули. Для другого блоку процес пошуку не розглянутих вантажівок необхідно пришвидшити. Наприклад, можна пам’ятати впорадковану множину або використати метод двох вказівників
Для того аби розв’язати задачу зауважимо, що якщо відрізок вибуху вантажівки \([a_j - b_j, a_j + b_j]\) є вкладений у відрізок вибуху іншої вантажівки \([a_i - b_i, a_i + b_i]\), тоді нам не вигідно стріляти в \(j\)-ту вантажівку, бо \(i\)-та підірве не менше вантажівок. Якщо ми не будемо пробувати підривати такі вантажівки як \(j\)-та, тоді вибух буде поширюватись незалежно вліво та вправо. Тобто, якщо ми детонацією зачепимо вантажівку справа, то вибух від неї пошириться не лівіше ніж був до того. А отже, ми маємо окремо порахувати скільки вантажівок ми підірвемо зліва і скільки справа, якщо вибухи незалежні. Тобто, вибухи \(i\)-ї вантажівки відбуваються у проміжку \([a_i - b_i, a_i]\) та \([a_i, a_i + b_i]\), відповідно для вибухової хвилі вліво і вправо. Для розвязання таких підзадач використаємо підхід динамічного програмування. Нехай \(L[i]\) — номер найлівішої вантажівки що ми можемо підірвати вибуховою хвилею вліво, якщо \(i\)-та вибухне. Аналогічно \(R[i]\) — номер найправішої вантажівки у випадку вибуховою хвилею вправо. Щоб обрахувати \(L[i]\) нам необхідно знайти найменше значення \(L[j]\) для якого виконується \(a_i - b_i \le a_j \le a_i\). Аналогічно, щоб обрахувати \(R[i]\) нам необхідно знайти найбільше значення \(R[j]\) для якого виконується \(a_i \le a_j \le a_i + b_i\). Такі значення можна знайти за допомогою структур даних, які вміють шукати мінімум на відрізку, і змінювати значення в точці. Наприклад, можна використати дерево відрізків. Маючи такі значення, ми знаємо, що підірвавши \(i\)-ту вантажівку, відповідь буде \(R[i] - L[i] + 1\). Відповіддю на задачу буде максимум з таких значень.
Зауважимо, що якщо вибухи не можна розглядати незалежно, тобто для вантажівок, вибухова хвиля яких є вкладеною, то значення \(R[i] - L[i] + 1\) може бути меншим ніж кількість вантажівок, які вибухнуть якщо першою підірвати \(i\)-ту. Проте, ми показали, що в такі вантажівки стріляти неоптимально, а це означає, що ми можемо проігнорувати це.
Перш за все в цій задачі необхідно було зрозуміти, що в нас задано кореневе дерево. Тоді дороги з даної вершини до вершин східніше це теж саме, що й ребра до синів в дереві. Отже, наш запит перетворюється у такий: порахуйте суму вершин в піддереві вершини \(v_i\) на відстані не більше \(d_i\).
Тоді для зручності порахуємо \(h[i]\) — глибину \(i\)-ї вершини, тобто відстань до кореня дерева. Для цього напишемо, наприклад, обхід в глибину. Тоді вершини в піддереві будуть мати глибину більшу ніж в кореня піддерева. А відстань від вершини до її предка рівна різниці їх глибин. А, отже, для того аби отримати бали за перший блок тестів достатньо було написати обхід дерева починаючи з вершини \(v_i\) і йдучи у вершини з більшою глибиною. І під час цього процесу додавати до відповіді значення вершини якщо вона має глибину не більшу за \(h[v_i] + d_i\). Такий розв’язок буде мати складність \(O(q \cdot n)\).
Для другого блоку тестів потрібно було помітити, що відстань від поточної вершини до усіх інших завжди менша за \(n\). Тоді наша задача перетворюється до того, що нам необхідно порахувати суму в піддереві. Що можна було зробити в обході де ми обраховуємо \(h[i]\) і запам’ятати в масиві \(sum\).
Тепер для блоку без обмежень необхідно помітити, що ми можемо додати значення \(sum[v_i]\) і нам потрібно буде відняти значення \(sum\) для вершин в піддереві на глибині \(h[v_i] + d_i + 1\). Бо вершини на такій глибині не мають бути враховані у відповідь і їхні піддерева теж, оскільки в них глибина ще більша. Якщо ми в початковому обході в глибину будемо додавати вершину в список вершин на такій глибині. Тоді для будь-якої вершини, усі вершини в її піддереві на певній глибині будуть іти підряд у списку для цієї глибини. А отже, нам необхідно знайти проміжок вершин на глибині \(h[v_i] + d_i + 1\), що належать піддереву вершини \(v_i\) і порахувати їх суму. Порахувати суму можна використавши префіксні суми, бо у нас немає ніяких змін.
Підзадача з пошуком меж проміжку є складнішою, для того аби її розв’язати запам’ятаємо Ейлерів обхід дерева. Це можна зробити в нашому початковому обході в глибину, запам’ятавши для вершини \(tin\) та \(tout\) — часи коли ми увійшли та вийшли з вершини. Знаючи такі значення ми можемо сказати чи вершина \(u\) є строго у піддереві вершини \(v\) просто перевіривши \(tin[v] < tin[u] < tout[u] < tout[v]\). Тепер ми можемо для глибини рахувати не список вершин, а список значень \(tin\) для цих вершин. Тоді такий список буде посортований, оскільки ми додаємо вершини в тому порядку, в якому їх відвідували. У такому списку нам потрібно знайти \(l\) — індекс найлівішої вершини на рівні, яка є в піддереві вершини \(v\). Тобто таку \(u\), в якої мінімальний \(tin[u] > tin[v]\). Також нам потрібно знайти такий \(r\) — індекс найправішої вершини на рівні, яка є в піддереві вершини \(v\). Тобто таку \(u\), в якої максимальний \(tin[u] < tout[v]\). Це будуть межі відрізка, суму на якому нам потрібно відняти. Щоб знайти такі межі ми можемо використати двійковий пошук по часах входу на відповідному рівні.
Перш за все у задачі потрібно було помітити те, що радіус \(R\) можна шукати двійковим пошуком. Оскільки збільшивши радіус кола ділянка ураження тільки збільшиться і не може втратити зв’язність. Тепер для радіусу \(R\) потрібно перевірити чи можна розташувати три кола такого радіусу щоб покрити 3 задані точки і щоб усі кола були з’єднані.
Тоді у нас є два випадки: кожне коло містить точку або одне з кіл містить дві точки. Випадок, коли одне коло може містити 3 точки можна не розглядати, так як ми могли посунути це коло до того моменту коли одна з точок стане ззовні. Тоді помістити її в інше коло і отримати таку ж ситуацію як у другому випадку.
Розглянемо перший випадок, кожна точка буде знаходитись в окремому колі. Тоді для того аби ділянка покрита цими колами була зв’язана то має бути одне коло яке зєднане з двома іншими.
Тоді центр такого кола має бути на відстані не більше \(R\) до вершини, що воно покриває, бо інакше воно не буде покривати цю вершину. Також відстань до інших двох точок має бути не більше ніж \(3 \cdot R\), бо якщо більше, тоді ми не зможемо поставити коло яке буде покривати цю вершину і мати спільну точку на цьому колі. Тепер нам потрібно сказати чи може існувати такий центр кола. Для цього подивимось чи кола радіусів \(R\), \(3 \cdot R\) та \(3 \cdot R\), в заданих вершинах, мають спільну точку. Бо геометричним місцем точок, що не далі ніж на відстані \(d\) від даної точки — це коло в даній точці радіусу \(d\). Зауважте, що нам потрібно розглянути до якої точки з 3-х заданих відстань має бути менша рівна за \(R\), а до інших двох \(\le 3 \cdot R\).
У другому випадку ситуація буде подібною, але тут центр кола що містить дві точки має бути на відстані не більше \(R\) від цих двох точок. А відстань до третьої має бути не більша за \(5 \cdot R\), оскільки ми можемо розмістити коло, що не містить жодну точку, як коло для з’єднання.
Отже, нам необхідно знайти чи кола з радіусами \(R\), \(R\) та \(5 \cdot R\) мають спільну точку. Аналогічно до попереднього варіанту нам необхідно розглянути яка з 3-х точок буде мати коло радіуса \(5 \cdot R\).
У двох випадках нам потрібно сказати чи три кола мають хоча б одну спільну точку.
Таку підзадачу можна розв’язати так: розглянемо перетин двох кіл і подивимось чи належить цей перетин третьому колу, якщо так тоді у кіл є спільна точка. Зауважимо, що перетину може й не бути, тоді нічого не будемо перевіряти. Також необхідно розглянути перетин кожної пари кіл. Такий аглоритм буде працювати якщо у нас немає кола яке лежить в іншому. Проте є лише один варіант коли одне коло всередині іншого і існує спільна точка для 3-х кіл, але описаний вище алгоритм скаже протилежне.
Фокус Зеника полягає у тому, що в кінці, після виконання вказаних операцій, буде число 47 для будь-якого початкового числа. Отже, задача зводиться до того аби перевірити чи число \(y\) рівне 47. Також можна було просто відтворити операції вказані в умові використовуючи заданий \(x\).
У задачі необхідно максимізувати значення \((a_i + j) - (a_j + i)\). Перегрупувавши доданки в цьому виразі отримаємо \((a_i - i) - (a_j - j)\). Якщо ми позначимо \(b_i = a_i - i\), тоді нам необхідно максимізувати \(b_i - b_j\). Для того аби максимізувати такий вираз нам необхідно вибрати \(b_i\), як максимальне значення в масиві \(b\). А \(b_j\) вибрати як найменше значення. І як відповідь вивести різницю \(b_i - b_j\).
Також зауважимо, що значення \((a_i + j) - (a_j + i)\) буде таке ж якщо в нас індексація масиву починається з нуля або з одиниці.
Для того аби здати перший блок тестів достатньо було перебрати усі підвідрізки які є в даному та порахувати для них суму. Відповідь буде рівна кількості тих у яких сума рівна 0. Складність такого розв’язку \(O(q \cdot n^3)\), оскільки підвідрізків є не більше ніж \(n^2\) і для кожного з них необхідно порахувати суму, що може займати до \(n\) операцій.
Щоб здати задачу на повний бал необхідно навчитись рахувати суму на підвідрізку швидше ніж за \(O(n)\). Наприклад, це можна зробити порахувавши суму чисел на кожному префіксі. Позначимо суму на префіксі довжиною \(i\) значенням \(pref_i\). Тоді сума на відрізку від \(l\) до \(r\) включно буде рівна \(pref_{r} - pref_{l - 1}\). Також суму на на відрізку \([l, r]\) можна перерахувати з суми на відрізку \([l, r - 1]\) додавши значення \(a_r\).
D. Турнірна таблиця обласної олімпіади
Розглянемо перший блок тестів, де є тільки запити на суму. Учасники не міняються місцями і суму нам необхідно порахувати на певному проміжку учасників, тому ми можемо порахувати значення \(pref_i\) — сума номерів перших \(i\) учасників. Відповідно \(pref_0 = 0\). Тоді сума номерів учасників на відрізку від \(l\) до \(r\) включно рівна \(pref_r - pref_{l - 1}\). Тепер нам необхідно навчитись визначати межі \(l\) та \(r\) для запиту. Для цього будемо пам’ятати \(pos_i\) — позиція учасника з номером \(i\). Тоді межі для запиту \(x_i\), \(k_i\) будуть такі: \(l = pos_{x_i} - k_i\) та \(r = pos_{x_i} - 1\).
Для блоку тестів, де немає запитів першого типу, помітимо те, що лише дві людини міняються місцями в одному запиті. А отже ми можемо оновити значення \(pos\) для цих двох учасників. І зауважимо, те що \(pref_i\) змінюється тільки в позиції \(pos_{x_i}\), а отже ми її можемо перерахувати.
Тепер для усієї задачі необхідно помітити, що Зеник не може обігнати більше ніж \(n + q\) учасників. Це тому, що початково перед ним може бути максимум \(n - 1\) учасник, і запит другого типу збільшує це значення максимум на 1. Ми вміємо оновлювати задачу коли учасник обганяє одного перед собою, тобто ми можемо \(x_i\) разів зробити так, що Зеник обганяє одного учаника перед собою. Сумарно він обжене не більше \(n + q\) учасників, тому сумарна складність \(O(n + q)\).
У реалізації винесено у функцію оновлення усіх значень коли учасник \(x\) обганяє одного учасника над собою.
Для того аби розв’язати задачу необхідно помітити, що останнє число ми можемо визначити порахувавши скільки нових інверсій воно створить. Якщо ця кількість \(x\), то це означає що лівіше є \(x\) чисел більших нього, і відповідно \(n - 1 - x\) чисел менших за нього, а отже його значення \(n - x\). Ми визначили останнє число і тепер можемо продовжити даний процес для передостаннього числа і так далі. Проте для наступних чисел ми повинні врахувати те, що деякі числа вже встановленні. Тобто якщо ми знаємо, що в нас на певному префіксі має бути \(y\) чисел менших за поточне, то нам необхідно вибрати \(y + 1\)-ше число, яке ще не встановлене. Це можна зробити за \(O(n)\). Тоді сумарна складність \(O(n^2)\).
Тепер для повної задачі нам потрібно швидко знаходити \(y + 1\)-ше не використане число. Один із варіантів — це встановити в позиції від 1 до \(n\) одиниці, і коли ставимо число, то в його позиції змінюємо 1 на 0. Тепер в нас стоятиме 1 тільки в позиціях чисел, які ще не встановлені. А отже нам потрібно знайти \(y + 1\)-шу 1-цю. Це є стандартна задача розглянута у відео лекції на тему «Дерево відрізків» на YouTube-каналі Algotester, якщо ми будемо шукати максимальний префікс із сумою \(y\). Тоді потрібне нам число знаходитиметься на наступній позиції. Тепер в цій позиції потрібно замінити 1 на 0.
Розглянемо простий дільник \(p\) числа \(n\), нехай \(b\) — степінь \(p\) в факторизації \(n\), тобто найбільше ціле число таке що \(n\) ділиться на \(p^b\). Якщо НСК(\(n-1, n-2, \dots, n-k\)) ділиться на \(n\), то це означає що ділиться і на \(p^b\). Також можна помітити, що для цього має існувати число, серед \(n - 1, n - 2, ..., n - k\), яке ділиться на \(p^b\). Нехай це число \(n - x\). Тоді оскільки \(n\) теж ділиться на \(p^b\) тоді з цього випливає, що і \(x\) ділиться на \(p^b\). А також ми можемо сказати, що \(p^b \le x\), а отже число \(p^b\) є серед чисел 1, 2, ..., \(k\). Отже якщо НСК(\(n - 1, n - 2, ..., n - k\)) ділиться на \(n\) тоді і лише тоді, коли НСК(1, 2, ..., \(k\)) теж буде ділитись на \(n\). Значить нам необхідно порахувати кількість дільників числа НСК(1, 2, ..., \(k\)). Для першого блоку тестів можна було порахувати це число, розглянути усі його дільники \(n\) та порахувати скільки з них більші за \(k\). Зі збільшенням \(k\) це значення буде дуже збільшуватись і такий розв’язок не можна буде використати для всієї задачі.
Для блоку з одним \(k\) можна помітити, що якщо ми зможемо представити НСК(1, 2, ..., \(k\)) у вигляді \(p_1^{b_1} \cdot p_2^{b_2} \cdot ... \cdot p_m^{b_m}\), тоді кількість дільників такого числа рівна \((b_1 + 1) \cdot (b_2 + 1) \cdot ... \cdot (b_m + 1)\). А також можна помітити що усі числа від 1 до \(k\) є дільниками НСК, тому ми можемо від кількості усіх дільників відняти \(k\). У попередньому абзаці ми показали, що НСК може ділитись на якесь \(p^b\) лише тоді коли \(p^b \le k\). А отже нам достатньо для кожного простого числа \(p \le k\) порахувати максимальне \(b\) таке, що \(p^b \le k\) і порахувати добуток \(b + 1\) по модулю.
Щоб розв’язати повністю задачу необхідно зрозуміти що зі збільшенням \(k\) для деяких \(p\) може збільшитись \(b\). Тому будемо опрацювувати запити в посортованому порядку. І посортуємо усі числа вигляду \(p^b\), що не перевищують \(10^7\). Використавши метод двох вказівників. Коли ми переходимо від одного \(k\) до іншого то деякі значення \(b\) зміняться, а отже нам потрібно буде оновити відповідь. Нам потрібно поділити на старе значення \(b\) + 1 і помножити на нове таке значення. Ділення по модулю на число \(x\), яке взяємнопросте з модулем \(M = 998244353\) — це те ж що і операція множення на число \(y\) таке, що \(x \cdot y \mod{M} = 1\). Для простого числа \(mod\) ми знаємо малу теорему Ферма: \(x^{M - 1} \mod{M} = 1\), а отже \(y = x^{M - 2} \mod{M}\) і його можна порахувати швидким піднесенням до степеня. Також оскільки значення \(b\) не більші за 23, то можна було порахувати обернене значення для кожного числа від 1 до 23 і записати це в масив.
При додаванні точки знайдемо найкоротшу відстань від неї до всіх інших наявних точок. Тепер перевіримо чи ця відстань менша ніж була перед тим. Також в нас є запити видалення, тому нам треба пам’ятати відповідь для попередньо доданих точок. Для цього можна використати стек — структуру яка може додавати елемент в кінець, видаляти з кінця і знати останній елемент стеку.
Для повної задачі необхідно зауважити те що точок на відстані не більшій ніж \(r\) від нової точки, де \(r\) — найменша відстань між всіма іншими точками, є небагато, і нам потрібно порахувати відстань тільки до цих кількох точок. Проте шукати точки на відстані не більше \(r\) від даної доволі складно, тому будемо шукати точки що знаходяться в квадраті з довжиною сторони \(2 \cdot r\) з центром в новій точці. Таких точок не може бути більше 9, тому що в кожному квадраті на рисунку не може бути двох точок, бо інакше була б пара точок що має відстань меншу за \(r\). А тому максимум може бути 9 точок.
Отже нам необхідно шукати точки в прямокутнику, вміти додавати і видаляти точки. Це можна робити використавши дерево відрізків, де в кожній вершині дерева відрізків будемо підтримувати множину точок, впорядковану за \(y\), для усіх точок в яких \(x\) покритий проміжком вершини. При операції додавання або видалення нам необхідно оновити значення в \(O(log)\) вершин, а в одній вершині оновлювати множину можемо за \(O(log)\). Тому складність для однієї операції буде \(O(log^2)\).
Зауважимо, що в межах чорних та білих діагоналей елементи можна рухати та переставляти довільним чином за 0 хвилин. Отже, кожна клітинка яка на початку розташована не на своїх діагоналях має бути переставлена на свої обміном за 1 хвилину. Оскільки за один хід ми переставляємо дві такі клітинки, то відповідь — це кількість клітинок, які початково не на своєму місці, поділена на два.
Єдині випадки, коли такого рядка не існує:
У послідовності є два значення 1, 3 або 3, 1 підряд. Тоді 2 символи на перетині повинні бути одночасно однаковими та різними, що неможливо.
У послідовності є три значення 3, 2, 3 підряд. Тоді перші 3 символи повинні бути однаковими, 4 символ повинен відрізнятись від них, а потім знову 3, 4 і 5 символ повинні бути однаковими, що неможливо.
Для решти послідовностей відповідний рядок завжди існує.
Подвоїмо масив \(a\). Для кожної початкової позиції \(i\) знайдемо значення \(L_i\) — найлівіший можливий індекс, де закінчується входження перестановки \(p\) як підпослідовності, якщо починаємо розглядати масив \(a\) починаючи з індексу \(i\). Маючи ці значення, можна для кожного циклічного зсуву перевірити чи він підходить.
Щоб порахувати \(L_i\) достатньо обчислити наступну динаміку: \(DP_i\) — найлівіший індекс, де закінчується входження перестановки \(p\), якщо ми зараз знаходимося в \(i\)-у елементі масиву \(a\) (і, відповідно, в \(j\)-у елементі перестановки \(p\), такому що \(p_j = a_i\), такий індекс є унікальний). Таку динаміку легко обчислити, якщо знайти значення \(Next_i\) — де в масиві знаходиться найближчий елемент, який є наступним в перестановці \(p\), після \(a_i\). Всі значення можна обчислити зі складністю \(O(n)\).
Розглянемо масиви часткових сум — \(sa[i] = a[1] + a[2] + \dots a[i]\). Аналогічно масив \(sb[i]\). Марічка може з’їсти перші \(x\) цукерок з першого ряду і перші \(y\) цукерок з другого ряду, якщо \(sa[x]+sb[y] \ge 0\).
Припустимо, що в обох масивах часткових сум максимальне значення розташоване в кінці масиву.
Нехай Марічка з’їла \(x\) цукерок з першого рядку і \(y\) з другого. Скажемо, що якщо Марічка їсть цукерки з одного з рядів, то їй вигідно це робити поки значення у відповідному масиві часткових сум не стане більшим за попереднє. Тобто, якщо Марічка їсть з першого ряду, то їй вигідно це робити поки вона не дійде до такого \(new_x\), що \(sa[new_x] \ge sa[x]\). Якщо дівчина може таким чином з’їсти з першого ряду всі цукерки до \(new_x\), то це точно вигідно, бо рівень задоволення Марічки стане більшим. Якщо ж Марічка не може цього зробити (рівень задоволення може стати від’ємним), то варто спробувати збільшити рівень задоволення за рахунок цукерок з другого ряду. Починати їсти з першого ряду тоді взагалі не вигідно, адже таким чином Марічка зменшить рівень задоволення, і можливо уже не зможе їсти з другого.
Тобто ми можемо порахувати позиції, де збільшуються значення часткових сум, а також які мінімальні значення зустрічаються між цими позиціями. Після цього жадно обираємо один з варіантів.
Якщо ж найбільші значення знаходяться не в кінці масиву, то даним алгоритмом Марічка може з’їсти усі цукерки до позицій, де знаходяться максимуми в обох масивах. Зауважимо, що далі можна розглядати усі значення з кінця і аналогічним алгоритмом розв’язати другу половину, адже позиції максимумів залишаться такими ж.
Складність такого розв’язку \(O(n)\).
Поділимо всі вершини на 4 групи по \(n \over 4\) вершини. В першу хвилину пофарбуємо в синій колір 1 і 2 групу вершин, у другу хвилину 1 і 3 групу, у третю хвилину 1 і 4 групу. Таким чином кожна пара вершин була пофарбована в один колір хоча б раз, а отже ми точно видалимо всі можливі ребра. Отже за 3 хвилини завжди можливо.
Тепер потрібно перевірити, чи можливо менше, ніж за 3 хвилини. Якщо у графі немає ребер, то відповідь 0. Це стається, коли у жодної пари чисел немає спільного одиничного біту.
Розглянемо певний біт, оберемо усі вершини, в яких цей біт рівний 1. Повинна існувати хвилина, в якому всі обрані вершини пофарбовані в один колір. Інакше за 2 хвилини не вийде видалити ребра між усіма парами обраних вершин.
Тоді за одну хвилину можна обрати 2 підмножини бітів (одну з них фарбуємо в синій колір, іншу в жовтий) так, щоб:
ці підмножини не перетиналися
для кожної з підмножин існувало не більше \(n \over 2\) чисел, які мають хоча б 1 біт з підможини
не існувало жодного числа, яке має біти з обох підмножин
Можна перебрати усі пари підмножин та перевірити ці умови за \(3^{18}\) операцій.
Тепер знайдемо усі підмножини бітів, які можливо покрити за одну операцію — об’єднання двох підмножин різних кольорів. Якщо можливо покрити всі біти за одну операцію, то відповідь 1. Інакше подивимось чи існують такі 2 підмножини, що в об’єднанні дають усі біти. Якщо так, то відповідь 2.
Нехай ми вибрали довільний підграф та пару вершин в ньому. Для всіх таких виборів подивимось, чи відстань між вибраною парою є не меншою за кількість листків. Якщо це так, то покращимо відповідь сумою ваг вибраних вершин. Неважко побачити, що це значення буде рівним відповіді на оригінальну задачу.
Підвісимо дерево за довільну вершину і зробимо динамічне програмування зі станом [корінь піддерева][відстань між двома вибраними вершинами мінус кількість листків у вибраному підграфі][параметр 0/1/2], де 0 — ще не почали прокладати шлях між двома вибраними вершинами, 1 — шлях проходить із довільної вершини в піддереві до його кореня, 2 — шлях повністю проходить в піддереві. Значенням цього стану є загальна вартість вибраних у підграф вершин.
Загальна складність \(O(n^2)\), оскільки другий параметр стану (баланс) може приймати значення від \(-c\) до \(c\), де \(c\) не більший за розмір піддерева.
Розв’язок 1
Скажемо, що елемент \(x\) лівий, якщо в першій перестановці його ліве входження, інакше правий. Тепер розглянемо 2 елементи \(a\), \(b\) (\(a<b\)) і їх відносне розташування:
\(aabb\): немає обмежень
\(bbaa\): відповідь 0
\(abba\): \(a\) — лівий
\(baab\): \(b\) — правий
\(baba\): \(a\) — лівий, \(b\) — правий
\(abab\): якщо \(a\) правий, то \(b\) теж правий; якщо \(b\) лівий, то \(a\) теж лівий
Нехай ми знайшли значення усіх елементів, які визначаються однозначно використовуючи дані обмеження. Подивимось на всі елементи, для яких ми ще не знаємо позицію. Можуть залишитись ланцюжки, де кожна пара сусідніх елементів перетинаються типом \(abab\). Розмежовані такі ланцюжки можуть бути елементами типу \(aabb\).
У кожному ланцюжку усі елементи на префіксі повинні бути лівими, а на суфіксі правими. Всі ці варіанти відрізняються, адже для них усіх відрізняється перша пара елементів, яка утворює інверсію, крім можливо варіанту, коли всі ліві чи всі праві. Такі 2 варіанти відрізняються, якщо існує якийсь уже відомий елемент, який попадає між елементами ланцюжка. Тобто відповідь потрібно домножити на \(len+1\), якщо є ще якийсь елемент, та на \(len\) якщо ні, де \(len\) — довжина ланцюжка.
Наприклад для [1, 1, 2, 3, 2, 4, 3, 4] елементи 2, 3, 4 утворюють ланцюжок довжиною 3 і не існує жодного іншого елемента, який з ним перетинається, тому домножуємо відповідь на 3. А для [1, 2, 3, 2, 4, 1, 3, 4] елемент 1 — лівий, елементи 2, 3, 4 утворюють ланцюжок довжиною 3, але оскільки елемент 1 перетинається з ланцюжком, то відповідь домножається на 4.
Знаходити ланцюжки можливо за \(O(n)\), якщо перебирати усі елементи від 1 до \(n\).
Розв’язок 2
Позначимо як \(a\) та \(b\) позиції одиниці в заданій послідовності (\(a < b\)). Порахуємо відповідь динамічним програмування \(R_a\) — кількість способів вибрати 2, 3, … \(n\) (в такому порядку) після позиції \(а\) так, щоб все решта (те що не взяли) правіше від \(а\) було унікальним. Те саме порахуємо для позиції \(b\) і додамо до відповіді.
Тепер потрібно відняти те, що порахували двічі. Щоб щось порахували двічі потрібно аби існував підрядок який починається в позиції \(a\) і проходить через позицію \(b\), який є мерджем двох впорядкованих послідовностей [\(1, 2, …, k\)]. В одному варіанті з нього взяли одну підпослідовність у відповідь, в іншому - іншу, тим сами генеруючи однакові підпослідовності. Тому знайдемо найкоротший такий підрядок і віднімемо від поточної відповіді відповідь на суфіксі після нього.
В задачі потрібно просто зробити те, що сказано в умові. Для спрощення написання коду, можна не будувати нову стрічку, а одразу рахувати суму.
Цікавий факт: крім банківських карток алгоритм Луна використовується для IMEI та номерів соціального страхування в Канаді.
Будемо перебирати \(p_i\) та ділити
\(n\) на \(p_i\), поки \(n\) ділиться на \(p_i\) без остачі. Якщо після цих операцій
ми отримали одиницю — відповідь YES
, інакше
NO
.
Цікавий факт: на квітень 2023, найбільше відоме людству просте число \(2^{82589933}-1\). Це число має \(24862048\) цифр.
Задачу можна розв’язувати незалежно по \(x\) і \(y\). Для однієї із координат відповіддю завжди буде одна із сусідніх пар в посортованому масиві. Достатньо вибрати із двох відповідей меншу. Під час сортування треба бути обережним, щоб також мінімізувати \(i+j\). Для цього слід сортувати не лише по координаті, а й по номеру.
Цікавий факт: Точка-У здатна гатити орків на відстані до 120км.
Нескладно помітити, що якщо \(b=c\), ми можемо досягти Помаранчевої Революції зробивши \(b\) червоно-голубих зустрічей.
Подивимося уважно, що стається із \((b-c)\) після зустрічі оранжевого і голубого:
\[\begin{gathered} a' = a - 1 \\ b' = b - 1 \\ c' = c + 1 + 1 + k \\ b' - c' = (b - c) - \textbf{(k+3)} \end{gathered}\]
Аналогічно після зустрічі оранжевого і червоного
\[\begin{gathered} a' = a - 1 \\ b' = b + 1 + 1 + k \\ c' = c - 1 \\ b' - c' = (b - c) + \textbf{(k+3)} \end{gathered}\]
Бачимо, що різниця не міняє остачі від ділення на \((k+3)\). Отже якщо \((b-c)\) не ділиться на \((k+3)\) націло, то отримати \(b=c\) неможливо і відповідь
NO
. Інакше відповідь YES
. Для знаходження
порядку зустрічей застосуємо жадібний підхід.
Цікавий факт: Вважають, що давні єгиптяни одними з перших бджолярів в світі.
Розгленемо будь-яку сторону квадрата. Припустимо ми зафіксували кутики. Можливо показати, що якщо обидва кутики є випуклими, то сторона буде валідною тоді і тільки тоді, якщо кількість частинок 5-го типу є на один більшою ніж 6-го. Аналогічно, якщо обидва кутики є впуклими, то кількість частинок 6-го типу має бути на один більшою за кількість частинок 5-го. Якщо ж кутики різного типу, то кількість частинок 5-го і 6-го типів повинна бути однаковою. Кількість частинок 7-го типу може бути будь-якою.
Переберемо парність \(n\) і кутики. Для кожної сторони виставимо обов’язкові частинки - можливо одну з 5-го або 6-го типу і можливо одну 7-го, щоб була потрібна парність. Після цього можна добирати будь-яку кількість пар - 5 і 6 або дві 7.
Тож ми можемо перебрати усі можливо рамки розміру 3х3 та 4х4 і максимізувати кількість можливих пар. Тоді щоб збільшити \(n\) на 2 потрібно використати 4 пари. Перебирати можна кутики з виставленням необхідних частинок. Або можна перебрати усі \(2^8\) та \(2^{12}\) варіантів з’єднань.
Код розв’язку з перебором кутиків
Код розв’язку з перебором варіантів
Цікавий факт: Вважають, що аматорським малюванням Казимир Малевич почав займатися в Конотопі.
Програшні позиції — многокутники, для яких відстань від лівого краю до правого рівна відстані від нижнього до верхнього \(max(x_i) - min(x_i) = max(y_i) - min(y_i)\) (назвемо такі многокутники обрізаними квадратами), і з них за одну операцію не можна відрізати многокутник з такими ж характеристиками. Можна довести, що з обрізаного прямокутника завжди можна за одну операцію вирізати обрізаний квадрат, з якого в свою чергу за одну операцію не можна вирізати обрізаний квадрат, тільки прямокутник: \(max(x_i) - min(x_i) \ne max(y_i) - min(y_i)\). Для цього підійде обрізаний квадрат найменшого розміру.
Імплементація: йдемо з лівого краю многокутника до правого і підтримуємо найвищу і найнижчу точку, таким чином ми знаємо: \(min(x_i)\) — лівий край, \(max(y_i)\) — координата \(y\) найвищої розглянутої точки, \(min(y_i)\) — координата \(y\) найнижчої розглянутої точки, \(max(x_i)\) — поточна \(x\) координата. Якщо в якийсь момент до досягнення правого краю рівність буде виконуватись, то виграє перший гравець. Аналогічний прохід треба зробити зліва направо, зверху вниз і знизу вверх. Якщо рівність ніколи не виконається — виграє другий гравець. Складність \(O(dx + dy + n)\).
Цікавий факт: найбільший спечений пляцок важив 10540 кг.
Проходимо по масиву часткових різниць зліва направо і підтримуємо кількість відкритих проміжків висоти 1 (ціна створення 1) та відкриті проміжки висоти \(x\) (ціна створення 1, але їх можна розбити на \(x\) одиничних проміжків за певну ціну). Проміжків висоти 1 в нас завжди буде менше, ніж \(х\); якщо більше, то поміняємо їх на один проміжок \(х\) з ціною розбиття 0. Маємо два випадки:
Часткова різниця \(a\) додатня. Поки \(a \ge x\) додаємо проміжок \(x\) з ціною \(x-1\) та 1 до відповіді. Залишилось \(a < x\), треба або відкрити \(a\) проміжків висоти 1 або відкрити 1 проміжок висоти \(x\) і закрити \(x-a\) проміжків висоти 1. Якщо кількість відкритих проміжків висоти 1 не менше \(x-a\): тоді закриваємо \(x-a\) одиничних і додаємо один проміжок висоти \(x\) з ціною \(a-1\), +1 до відповіді. Інакше, збільшуємо кількість відкритих одиничних відрізків на \(a\) і якщо вигідніше розбити найдешевший (нехай його ціна \(p\)) \(x\) проміжок для об’єднання \(p + 1 < x\), то розбиваємо його і додаємо до відповіді \(p+1\) і формуємо новий \(x\) проміжок з ціною \(a-1\), інакше просто додаємо до відповіді \(a\).
Часткова різниця \(-a\) від’ємна. Аналогічно поки \(a \ge x\) закриваємо найдорожчий проміжок висоти \(x\). Тепер ми можемо або закрити \(a\) проміжків висоти 1 і нічого не платити, або закрити один \(x\) і відкрити \(x-a\) 1 і заплатити \(x-a\). Якщо в нас є \(a\) проміжків висоти 1, то закриваємо їх і міняємо проміжок висоти \(x\) на інший з ціною \(x-a\) якщо це вигідно (вона менша). Якщо немає, тоді можливо вигідно поміняти найдешевший (нехай його ціна \(p\)) \(x\) на проміжки висоти 1. Тоді в першому випадку ми платимо \(p\), в другому \(x-a\). Тобто якщо \(p < x - a\), то заплатимо \(p\), закриємо цей проміжок висоти \(x\) і можемо змінити найдорожчий відрізок \(x\) на інший з ціною \(x-a\); інакше заплатимо \(x-a\) і видалимо найдорожчий відрізок \(x\) (треба видалити відрізок ціною \(x-a\) і можна замінити найдорожчий відрізок \(x\) на інший з ціною \(x-a\) => просто видалимо найдорожчий відрізок \(x\)).
Складність \(O(n \cdot log(n))\).
Цікавий факт: Бар Шона в Ірландії працює безперервно ще з середньовіччя.
У даній задачі достатньо просимулювати процес з умови, використовуючи цикл while.
Неважко переконатися, що наступний паттерн задовольняє умову задачі:
xoxoxo...
xoxoxo...
oxoxox...
oxoxox...
xoxoxo...
xoxoxo...
.........
Покажемо, що Зенику оптимально видалити або якусь кількість сторінок з початку, або з кінця щоденника. Припустимо, що Зеник вирвав якісь сторінки \(L, L + 1, …, R\) з середини щоденника, але залишив і першу, і останню сторінки (тобто \(1 < L \le R < n\)). Тоді розглянемо середнє арифметичне оцінок на сторінках \([1, L - 1]\) (нехай це буде якесь число \(А\)), і середнє арифметичне оцінок на сторінках \([R + 1, n]\) — \(B\). Якщо \(B \le A\), то Зеник міг би вирвати всі сторінки від \(L\) до \(n\), при цьому не погіршивши загальне середнє, а якщо \(A \le B\), то він би міг вирвати всі сторінки від 1 до \(R\), також не погіршивши загальне середнє.
Таким чином, достатньо просто перебрати всі можливі префікси та суфікси заданого масиву і вибрати серед них максимальний. Це неважко зробити з лінійною складністю просто ітеруючись по масиву та підтримуючи кількість і суму оцінок.
Розв’яжемо дану задачу для двох точок \((x_1, y_1)\) і \((x_2, y_2)\). Якщо \(x_1 + y_1 \mod 3 \neq x_2 + y_2 \mod 3\), то відповіді не існує, оскільки ходи не змінюють остачу від ділення на 3 для суми координат. Неважко переконатись, що існує єдина точка \((x, y)\), у яку можна пересунути точки, використовуючи мінімальну кількість ходів.
Уміючи розв’язувати задачу для 2 точок, ми можемо зводити задачу з розміру \(n\) до розміру \(n - 1\) поки \(n \ge 2\).
Розглянемо найнижчу вершину \(u\), яку потрібно атакувати. Хаймарс вигідно ставити у найвищого предка \(u\), з якого ще можливо атакувати \(u\), оскільки таким чином він уразить найбільшу кількість вершин. Після цього можна видалити всі вершини з руснею, уражені хаймарсом, і повторити процес.
Схожий процес можна реалізувати, використовуючи алгоритм пошуку у глибину, підтримуючи для кожної вершини найглибшу русню і найнижчого хаймарса у піддереві.
Для початку посортуємо роботи за прибутком. Обчислимо масив \(q\) з імовірностями потрапити на роботу кращу за \(i\) за один місяць.
\(q_n = 0, q_{n-1} = p_n, q_{n-2} = q_{n-1} + (1 - p_n) (p_{n-1}), q_{n-3}=...\)
Далі будемо рахувати вклад роботи \(i\) у відповідь. Легко бачити, що перша робота приносить значення \(a_1 \cdot \sum_{j=1}^{m}(1 - q_1)^j\) до відповіді. Для 2 роботи вклад можна порахувати за допомогою принципу включення-виключення: \(a_2 \cdot \sum_{j=1}^{m}((1 - q_2)^j - (1 - q_1)^j)\). У цій формулі \((1 - q_2)^j\) означає що Зенику не вдалось потрапити на роботу кращу за 2, \((1 - q_1)^i\) потрібно відкинути, щоб виключити імовірність залишитись у першій компанії. Аналогічно значення можна порахувати для роботи \(i\).
Суму \(\sum_{j=1}^{m}(1 - q)^j\) порахуємо використовуючи формулу суми геометричної прогресії.
Припустимо Зеник найняв вже \(k\) людей. Розглянемо початкову множину їх зарплат \(A\). Зрозуміло, що не має сенсу подвоювати зарплату працівнику з найбільшою початковою зарплатою. Для кожного іншого працівника, будемо подвоювати його зарплату допоки вона не стане більшою за \(max(A) / 2\).
Тепер посортуємо всіх працівників за новими зарплатами — \(a_1 \le a_2 \le a_3 ... \le a_k < 2a_1\). Зрозуміло, що з цього моменту часу все, що може зробити Зеник це подвоїти зарплати якійсь кількості працівників з найменшими зарплатами. Якщо Зеник залишить все як є, то нерівність буде \(a_k - a_1\). Якщо ж він подвоїть зарплати першим \(1 \le i < k\) працівникам, то нерівність буде \(2a_i - a_{i+1}\). Тому підтримуватимемо множину \(S\) таких значень.
Припустимо тепер Зеник захоче найняти ще одного працівника з початковою зарплатою \(x\). Аналогічно подвоюватимемо цю зарплату доки вона не перевищить \(max(A) / 2\). Тепер є два випадки:
\(x \le max(A)\). Тоді якщо \(a_i \le x \le a_{i+1}\), то потрібно видалити з множини \(S\) число \(2a_i - a_{i+1}\) та вставити два нові відповідні числа (якщо \(x < a_1\), то просто вставити одне нове число).
\(x > max(A)\). Тоді додамо \(x\) в множину \(А\) та почергово будемо подвоювати зарплату найменш оплачуваному працівнику, аби знову досягти вищеописаного інваріанта \(min(A) * 2 > max(A)\). Підтримуватимемо при цьому актуальні значення множини \(S\).
Можна помітити, що впродовж всього часу жоден працівник не отримає подвоєнь зарплати більше аніж \(\log (max(A))\) разів. Тому сумарна кількість подвоєнь продовж всього процесу — \(O(n \log (max(A))\), а кожну таку операцію можна виконувати за час \(O(\log n)\) використовуючи, наприклад, set або map. Тому сумарна складність становитиме \(O(n \log n \log(max(A))\).
Зеник розіб’є \(k\) задач на 2, а \(n - k\) задач він не змінюватиме, отже в нього буде \((2 \cdot k) + (n - k) = n + k\) задач. Тому в задачі достатньо перевірити чи це число не більше ніж 26.
Одним із розв’язків \(x_i^2 + y_i^2 = 2 \cdot (a_i^2 + b_i^2)\) є \(x_i = a_i - b_i\) та \(y_i = a_i + b_i\).
Переконаємось у правильності цього розв’язку: \(x_i^2 + y_i^2 = (a_i - b_i)^2 + (a_i + b_i)^2 = a_i^2 - 2 \cdot a_i \cdot b_i + b_i^2 + a_i^2 + 2 \cdot a_i \cdot b_i + b_i^2 = 2 \cdot (a_i^2 + b_i^2)\).
Оскільки нам необхідно знайти пару \(x_i, y_i \ge 0\), тому візьмемо \(x_i = |a_i - b_i|\), що не змінює правильність розв’язку.
Розглянемо декілька станів гри:
\(a = b\) — в такому стані виграє другий, бо він завжди може зробити симетричний хід і повернутись до цього ж стану, але з меншою кількістю камінців і стан \(a = b = 0\) програшний.
\(a > b\) — перший гравець може зробити дві купки рівні і тоді другий гравець буде у програшному стані
\(a < b\) та \(b - a \le \lfloor \frac{b}{2} \rfloor\) — у цьому стані першому необхідно забрати \(b - a\) камінців з купки другого. Перший гравець може забрати не більше ніж \(\lfloor \frac{b}{2} \rfloor\), отже він зможе зробити дві купки рівними.
\(a < b\) та \(b - a > \lfloor \frac{b}{2} \rfloor\) — у цьому стані по аналогії до попереднього випадку перший гравець не зможе своїм першим ходом зробити дві купки рівні, після його ходу буде і надалі виконуватись умова \(a < b\). Тобто перший перейде у такий стан в якому другий має виграшну стратегію, аналогічно до другого випадку.
Узагальнюючи усі умови можна сказати, що перший гравець виграє якщо \(2 a \ge b\) та \(a \ne b\).
У рівнянні \(f(k) = m\) ми знаємо, що існує \(p\) таке, що \(k + p = m\) та \(k\) ділиться на \(p\), отже і \(m\) теж ділиться на \(p\). Отже, кандидатами на розв’язок є числа \(k = m - p\), де \(p\) є простим дільником \(m\). Для того аби мати хоча б \(n\) кандидатів на розв’язок, необхідно аби число \(m\) містило хоча б \(n\) різних простих.
Тому розглянемо число \(m = 2 \cdot 3 \cdot 5 \cdot ...\) — добуток перших \(n > 1\) простих чисел. Це число є найменшим числом, для якого рівняння \(f(k) = m\) має хоча б \(n\) кандидатів на розв’язок.
Розглянемо один із його простих дільників \(p\), тоді доведемо, що \(f(m - p) = m\). Для цього нам потрібно довести, що немає такого простого дільника \(q < p\), що \(m - p\) ділиться на \(q\). Припустимо, що такий дільник існує, оскільки ми вибрали число \(m\) як добуток перших \(n\) простих чисел, то й серед цих простих чисел є \(q\). Отже, \(q \mid m\), оскільки \(p\) просте то \(q \nmid p\), отже \(q \nmid (m - p)\). Отримали суперечність, отже ми довели що \(f(m - p) = m\), оскільки різних \(p\) є \(n\) отже рівняння \(f(k) = m\) має хоча б \(n\) розв’язків.
Будемо шукати відповідь у вигляді рівнобедреного трикутника.
Для пошуку рівнобедреного трикутника використаємо двійковий пошук кута між двома рівними сторонами трикутника \(2 \cdot \alpha\), у випадку \(\alpha = 0\) (вироджений трикутник) відношення \(\frac{r}{P}\) дорівнює нулю, а у випадку \(\alpha = 30^{\circ}\) (рівносторонній трикутник) відношення максимальне. Отже, нам усього лише необхідно вивести формулу відношення — \(f(\alpha)\).
\(P = 2 \cdot r \cdot ctg(\alpha) + 4 \cdot r \cdot ctg(45^{\circ} - \frac{\alpha}{2}) \implies \frac{r}{P} = (2 ctg(\alpha) + 4 ctg(45^{\circ} - \frac{\alpha}{2}))^{-1}\).
Графік цієї функції зображено на рисунку. Бачимо, що функція монотонна, отже можна скористатися двійковим пошуком.
Якщо в несправедливій шерензі залишити тільки числа більші за деяке число \(x\), то шеренга залишиться несправедливою для будь-якого \(x\).
Розглянемо вигляд шеренги якщо залишити усі числа строго більші за \(x\), нехай таких чисел \(k\). Після цього подивимось, скільки є способів вставити числа, що рівні \(x\) у цю шеренгу. Для чисел \(x\) є \(k+1\) позиція, куди їх можна вставити.
Назвемо числа \(y\) з шеренги, що задовольняють \(y < 2 x\) малими.
У несправедливій шерензі не могли стояти поруч два малих числа, бо тоді вони б порушували умову несправедливості.
Число \(x\) не можна ставити в шеренгу поруч (ні ліворуч, ні праворуч) з малим числом, бо знов тоді порушимо умову несправедливості.
Позначимо кількість малих чисел \(s\). Залишається \(k+1-2s\) позицій, куди можна вставити числа \(x\), бо кожне мале число забороняє дві позиції: ліворуч і праворуч від себе.
Нехай \(p\) — кількість чисел \(x\), які потрібно вставити.
Ми вибираємо \(p\) з \(k + 1 - 2 \cdot s\) позицій \(C^{p}_{k+1 - 2 s}\) способами.
Зауважимо, що ця формула не залежить від розташування чисел у шерензі, отже відповідь буде рівна добутку значень \(C^{p}_{k+1 - 2 s}\) для всіх можливих \(x\).
Почнімо з простішої версії. Розглянемо випадок, коли \(n\) і \(m\) парні. Тоді ми можемо розділити нашу кімнату на ділянки з розміром \(2 \times 2\), і замостити кожну таку ділянку. Для того щоб замостити ділянку з розміром \(2 \times 2\) можна поставити по одному L-троміно кожного з чотирьох типів. Тоді кожна клітинка буде покрита тричі.
Тепер розглянемо випадок, коли \(n\) або \(m\) непарне. Без втрати загальності вважатимемо, що \(n\) — непарне. Тоді ми можемо розділити кімнату на дві частини з розмірами \(3 \times m\) та \((n - 3) \times m\). Оскільки \(n\) непарне, то \((n - 3)\) парне, отже ми можемо покрити частину з розміром \((n - 3) \times m\) описаним раніше способом. Щоб покрити ділянку з розміром \(3 \times m\), розділимо її на частини з розміром \(3 \times 2\). Покрити таку частину можна двома L-троміно. Оскільки клітинки з іншої частини ми покрили тричі, то частинки з розміром \(3 \times 2\) потрібно також покрити тричі.
Тепер перейдімо до складнішої версії. Єдиний випадок, який ми ще не розглянули, коли \(n\) і \(m\) непарні. Зауважимо, що кімнату з розміром \(7 \times 7\) можна покрити так:
Тут поле \(2 \times 2\) покриваємо описаним раніше способом, а кожну іншу L-троміно ставимо тричі.
Тоді можна розділити нашу кімнату на частини з такими розмірами: \(7 \times 7\), \((n - 7) \times 7\), \(7 \times (m - 7)\) та \((n - 7) \times (m - 7)\). Зауважимо, що \(n - 7\) та \(m - 7\) парні, тому ми зможемо покрити кожну з частин.
Помітимо, що щасливе число \(a + b\) завжди менше за 444444. Тому у цій задачі достатньо перебирати доданок \(b\) до \(5 \cdot 10^5\) та перевіряти, чи є \(a + b\) щасливим числом. Зауважимо, що при перевірці щасливості треба уважно розглянути випадки коли \(a\) або \(b\) рівні 0.
B. Щасливі числа без послідовних четвірок
Використаємо підхід динамічного програмування. Використовуватимемо такі позначення:
\(ans_i\) — відповідь на задачу для \(i - 1\), тобто сума щасливих чисел, довжина яких строго менша за \(i\).
\(dp_{4, i}\) — сума щасливих чисел, що мають довжину \(i\) та останню цифру 4.
\(cnt_{4, i}\) — кількість щасливих чисел, що мають довжину \(i\) та останню цифру 4.
\(dp_{7, i}\) — сума щасливих чисел, що мають довжину \(i\) та останню цифру 7.
\(cnt_{7, i}\) — кількість щасливих чисел, що мають довжину \(i\) та останню цифру не 4 (це буде цифра 7, або число з 0 цифр).
Ці значення можна обраховувати за такими формулами:
\(ans_i = ans_{i - 1} + dp_{4, i - 1} + dp_{7, i - 1}\)
\(dp_{4, i} = 10 \cdot dp_{7, {i - 1}} + 4 \cdot cnt_7\)
\(cnt_{4, i} = cnt_{7, {i - 1}}\)
\(dp_{7, i} = 10 \cdot dp_{4, {i - 1}} + 7 \cdot cnt_{4, {i - 1}} + 10 \cdot dp_{7, {i - 1}} + 7 \cdot cnt_{7, {i - 1}}\)
\(cnt_{7, i} = cnt_{4, {i - 1}} + cnt_{7, {i - 1}}\)
Початково для довжини 0 використовуватимемо такі значення: \(ans_0\) = 0, \(dp_{4, 0}\) = 0, \(dp_{7, 0}\) = 0, \(cnt_{4, 0}\) = 0, \(cnt_{7, 0}\) = 1. Ідейно ми пробуємо дописати одну цифру справа до числа. Такий розв’язок працюватиме за \(O(n)\), що занадто повільно.
Запишемо вектор \((ans_i, dp_{4, i}, cnt_{4, i}, dp_{7, i}, cnt_{7, i})\). Зробимо перехід від довжини \(i\) до довжини \(i + 1\) за допомогою множення матриці.
\[\begin{gathered} \begin{pmatrix} ans_i \\ dp_{4, i} \\ cnt_{4, i} \\ dp_{7, i} \\ cnt_{7, i} \end{pmatrix} = \begin{pmatrix} 1 & 1 & 0 & 1 & 0 \\ 0 & 0 & 0 & 10 & 4 \\ 0 & 0 & 0 & 0 & 1 \\ 0 & 10 & 7 & 10 & 7 \\ 0 & 0 & 1 & 0 & 1 \end{pmatrix} \cdot \begin{pmatrix} ans_{i - 1} \\ dp_{4, {i - 1}} \\ cnt_{4, {i - 1}} \\ dp_{7, {i - 1}} \\ cnt_{7, {i - 1}} \end{pmatrix}\end{gathered}\]
Тепер нам треба помножити зліва дану матрицю \(n + 1\) раз на початковий вектор. Тоді відповідь буде знаходитися в першій комірці нашого вектора. Оскільки множення матриць є асоціативною операцією, то можна знайти матрицю в степені \(n + 1\) та помножити її на початковий вектор. Це можна зробити двійковим піднесенням до степеня. Зауважимо, що всі операції множення та додавання потрібно виконувати за модулем \(10^9 + 7\). Загальна складність \(O(5^3 \cdot log(n))\).
Якщо рядок складається лише з цифр 4 або лише з цифр 7, то відповідь -1. Можна довести, що якщо підрядки довжини \(n\) та довжини \(n - 1\) є паліндромами, то це можливо тоді і тільки тоді коли рядок складається лише з 4 або лише з 7, а тому, якщо рядок не є паліндромом, то відповідь \(n\), інакше відповідь \(n - 1\).
Зробимо операції для кожного рядка так, що в першому стовпці всі значення були рівні 4. Після цього для кожного рядка потрібно або більше не робити операції або зробити 3 операції — перетворити на 7.
Назвемо рядок синім, якщо робимо 0 операцій, і жовтим, якщо 3.
Тепер дивимось на стовпці:
Якщо в стовпці всі значення однакові, зробимо їх рівними 4. Після цього нам байдуже чи робимо ще 3 операції, чи ні.
Якщо в стовпці 2 різних значення і можна зробити операції до цього стовпця так, щоб ці значення були 1 та 7. Тоді всі рядки з 1 повинні бути жовтими, 7 — синіми.
Якщо в стовпці 2 різних значення і можна зробити операції до цього стовпця так, щоб ці значення були 4 та 7. Тоді можливо 2 випадки: залишаємо 4, 7 — тоді всі 7 повинні бути синіми, або робимо зі значень 1 та 4 — тоді всі 1 повинні бути жовтими. Тобто ми можемо розбити всі рядки на 2 групи та, або всі елементи першої групи повинні бути жовтими, або всі елементи другої групи повинні бути синіми. Сформулюємо це так, що, якщо є хоча б один жовтий елемент другої групи, то всі елементи першої групи жовті. І якщо є хоча б один синій елемент першої групи, то всі елементи другої групи сині.
Якщо в стовпці 3 різних значення і можна зробити операції до цього стовпця так, щоб ці значення були 1, 4 та 7. Тоді всі рядки з 1 повинні бути жовтими, 7 — синіми.
В будь-якому іншому варіанті відповідь не існує.
Знайдемо всі значення рядків, які можливо знайти використовуючи ці умови. Якщо немає суперечностей, коли один рядок повинен бути одночасно і синім і жовтим, то відповідь існує. Також це можливо сформулювати як задачу 2-sat.
Перший масив побудуємо так, щоб в ньому було \(n\) щасливих чисел довжиною 10. Це можна зробити перебравши всі маски довжини 10 і замінювати біти зі значенням 0 на 4, а зі значенням 1 на 7. Таких масок є \(2^{10}\) > 747.
Другий масив побудуємо так, щоб в ньому було \(m\) перших щасливих чисел, помножених на \(10^{10}\). В нас є 2 числа довжини 1, 4 довжини 2, 8 довжини 3 і так далі. Отже, нам досить мати 9 цифр, щоб скласти 747 чисел. Тоді найбільше число займатиме не більше ніж 19 цифр і буде меншим ніж \(10^{19}\) < \(2^{64}\).
Нехай кількість цифр 4 у рядку є парною, а кількість цифр 7 -
непарною. Тоді, якщо усі цифри 4 у рядку стоять послідовно, то відповідь
NO
— ми не зможемо видалити усі цифри 4, адже останні дві 4
точно будуть сусідніми.
Інакше відповідь YES
— розглянемо кожну групу цифр 4
підряд, видалимо всі крім одного або двох залежно від парності. Після
цього повидаляємо всі 4 беручи пари з різних груп. Залишились лише
символи 7 — видалимо їх всіх крім одного.
Якщо ж кількість цифр 4 у рядку є непарною, а кількість цифр 7 - парною, то розмірковуємо за аналогією.
Припустимо, що Зеник знає дорогу \((u, v)\) таку, що
Відстань між барами \(u\) та \(v\) для Марічки не менша 3.
Зеник може добратись до бару \(u\) або до бару \(v\) швидше ніж Марічка.
Тоді Зеник приходить в один з цих барів та кожного разу, коли Марічка опиняється в сусідньому з ним барі, переходить по цій дорозі. Так він зможе постійно тікати від Марічки.
Інакше Марічка завжди зможе наздогнати Зеника. Якщо ми розглянемо дерево Марічки, то Зеник зможе лише не може покинути те саме піддерево — він зможе перестрибнути вершину Марічки, але Марічка наступним ходом зможе також попасти в цю вершину, тож це не має сенсу. Тому Марічка може просто іти в напрямку Зеника.
Зенику ж вигідно знайти таку вершину, що до неї йому ближче, ніж Марічці, по дорозі до цієї вершини Зеник теж заходить лише в вершини, які йому ближче, та відстань від початкової позиції Марічки до цієї вершини максимальна — це і буде відповідь. Тож Зеник перейде в цю вершину і буде чекати там Марічку.
Якщо \(l_1 > 1\) та \(l_2 > 1\), то відповідь 1. Тепер припустимо \(l_1=1\), тоді якщо \(l_2>r_1+1\), то відповідь рівна \(r_1+1\), інакше \(max(r_1, r_2)+1\).
Іншим розв’язком буде побачити, що відповідь може бути лише 1, \(r_1+1\) або \(r_2+1\). Ми можемо спробувати усі 3 варіанти та вибрати найменший.
Погрупуємо усі улюблені рядки за кількістю символів B
всередині. Неважко зрозуміти, що кожній такій групі буде відповідати
підрядок у рядку-відповіді, який буде складатись із відповідної
кількості символів B
. Між такими рядками слід поставити
\(max(a, c)\) символів A
,
а з лівого та правого краю по \(a\) та
\(c\) відповідно. Тому, відповідь це
\((1 + 2 + ... + b) + max(a,c) \cdot (b-1) + a
+ c = \frac{b(b+1)}{2} + max(a,c) \cdot (b-1) + a + c\).
Розглянемо такий індекс \(i\), де досягається мінімум \(|a_i-b_i|\). Поставимо на \(i\)-ту позицію різні значення в обидвох стрічках.
Для усіх інших позицій поставимо однакові значення в обох стрічках такі, щоб ми не обрали жодного значення з проміжку \([min(a_i, b_i), max(a_i, b_i)]\). Зауважимо, що не можливо, щоб для певного \(j\) і \(a_j\) і \(b_j\) були з цього проміжку, адже тоді значення \(|a_j-b_j|\) буде меншим за \(|a_i-b_i|\).
Тож відносний порядок не зміниться якщо в проміжному масиві замінити \(a_i\) на \(b_i\), оскільки не обрано жодного іншого значення між ними.
Знайдемо вершину з найменшою відстанню, яка відома. Якщо такої немає, то заданий граф — бамбук, і відповідь це обидва його кінці. Якщо така є, і її відстань дорівнює 1, то можна перебрати усіх сусідів, для яких невідома відстань та за \(O(n+m)\) використовуючи bfs перевірити, чи може вона бути відповіддю. Оскільки сусідні до цієї вершини ребра можуть проходити лише на сусідні відстані, таких вершин не може бути більше ніж 3.
Розглянемо тепер випадок, коли відстань до цієї вершини більша за 1. Неважко побачити, що вершини з невідомими відстанями та ребра між ними утворюють набір графів-бамбуків, оскільки ребра між ними можуть проходити лише між сусідніми значеннями відстані, і для кожної відстані є лише одна невідома вершина. Тож, як і в попередньому випадку, переберемо усіх невідомих синів знайденої вершини, і перевіримо для кожного із них обидва кінці бамбука, якому вона належить.
Отже, загальна складність: \(O(n+m)\).
Розглянемо найнижчу стіну, серед однакових візьмемо найлівішу. Нехай вона знаходиться на позиції \(i\), її висота \(a\). Щоб для цієї стіни виконувалась умова, необхідно, щоб у всіх правіших стінах була хоча б одна дірка на висоті не більшій \(a\). Зробимо дірку на висоті \(a\) у всіх правіших стінах висота яких більша за \(a\). Тоді для всіх стін правіше необхідна умова також виконується, крім того, ми зробили мінімальну можливу кількість дірок, адже ми не робили дірки у всіх стінках висоти \(a\).
Тепер розглянемо найнижчу стінку лівіше від \(i\). Нехай вона знаходиться на позиції \(j<i\), її висота \(b>a\). Є 2 варіанти, що робити:
Зробимо дірку на висоті \(a\) у всіх стінках від \(j\) до \(i\).
Зробимо дірку на висоті \(b\) у всіх вищих за \(b\) правіше стінки \(j\).
Порахуємо, який варіант робить меншу кількість дірок. Далі розглянемо наступну найменшу стінку лівіше від \(j\). Для неї буде також 2 варіанти: або робимо дірки на тій же висоті, що й для \(j\)-ої стінки на проміжку до \(j\), або робимо дірки на висоті самої стінки у всіх вищих правіше неї. Якщо ми обираємо двічі підряд перших варіант, то необхідно зробити ще одну дірку в стіні \(j\) на висоті \(a\).
Тож розв’язком буде кожного разу робити меншу кількість дірок, враховуючи можливо 1 додаткову. Якщо обидва варіанти однакові варто обирати другий, адже тоді ми точно не будемо робити додаткову дірку.
Складність такого розв’язку \(O(n \log (n))\).
Проміжки, які повністю знаходяться лівіше (правіше) за \(x\) дають обмеження на те, що лівий (правий) край відповіді не повинен переходити за їх середину. Тому їх усіх можна опрацювати окремо підтримуючи в сеті усі обмеження зліва та справа.
Розглянемо тепер усі інші проміжки. Якщо середина якогось проміжку \(\frac{l+r}{2}\) знаходиться лівіше (правіше) за \(x\), то це означає, що якщо наша відповідь більша за половину довжини \(\frac{r-l}{2}\), то лівий (правий) край повинен бути не лівіше (не правіше) за середину. Якщо ж середина проміжку попадає в \(x\), то або лівий чи правий край буде в точці \(x\) та цей проміжок не накладе обмеження, або в протилежному разі, довжина проміжку відповіді не повинна перевищувати половину довжини проміжку.
Використовуючи описані вище факти, відповідь можна знаходити за допомогою бінарного пошуку, в якому для поточної довжини потрібно вміти знаходити найменші обмеження як зліва, так і справа. Це можна зробити за допомогою підтримки дерева відрізків для знаходження мінімуму на префіксі.
Розглянемо 2 пари \((a_1, b_1)\) та \((a_2, b_2)\) та спробуємо зрозуміти, чи можуть вони обидві одночасно бути успішними. Нехай \(dist(a_1, b_1) \ge dist(a_2, b_2)\), тоді спершу успішною повинна стати перша пара, далі друга, адже значення діаметра не може зростати при видаленні вершин. При рівності пари одночасно повинні стати успішними.
Нехай \(c_1\) — середина шляху від \(a_1\) до \(b_1\). Це може бути як вершина, так і ребро, для зручності будемо розглядати, що це вершина, для подальшого розв’язку це не має значення, а також явно знаходити \(c_1\) не буде потрібно. Видалимо всі вершини \(v\) такі, що \(dist(c_1, v) > dist(c_1, a_1)\). Після цього пара \((a_1, b_1)\) стала успішною. Тож коли ж зможе після цього стати успішною пара \((a_2, b_2)\)? Якщо не видалили жодну з цих вершин. Тобто можна перевірити, що \(dist(a_2, c_1) \le dist(a_1, c_1)\) та \(dist(b_2, c_1) \le dist(a_1, c_1)\). Цю умову також можна зробити без знаходження \(c_1\): достатньо перевірити, що усі значення \(dist(a_1, b_1)\), \(dist(a_1, b_2)\), \(dist(a_2, b_1)\) та \(dist(a_2, b_2)\) не більші за \(dist(a_1, b_1)\).
Зауважте також, якщо виконується умова, після того, як ми зробили успішною пару \((a_1, b_1)\) ми можемо зробити успішною пару \((a_2, b_2)\) залишивши усі вершини, які знаходяться не далі за \(dist(a_2, b_2) / 2\) від середини шляху між \(a_2\) і \(b_2\).
Тепер нехай у нас є багато пар, потрібно визначити, чи можливо зробити їх усіх успішними. Успішними вони можуть ставати в порядку за спаданням відстані між вершинами. Якщо є пари з однаковою довжиною, то вони повинні стати одночасно успішними, тому байдуже в якому порядку їх розглядати. Необхідну умову також достатньо перевіряти лише між сусідніми парами у такому порядку, адже ми зможемо завжди підтримувати умову, що залишаться усі вершини не дальші за половину відстані від центру.
Тепер, щоб відповідати на запити, порахуємо для кожного \(l\) таке найбільше \(R_l\), що ми можемо зробити усі пари від \(l\) до \(R_l\) успішними. Зрозуміло, що для усіх \(r<R_l\) усі пари від \(l\) до \(r\) також можна зробити успішними. Будемо робити це методом 2 вказівників, а також підтримувати сет пар посортованих за відстанню, де між кожною парою сусідніх пар будемо перевіряти умову.
Складність такого розв’язку \(O(n \log n)\).
В задачі треба було додати три числа, і від суми відняти максимум з трьох заданих чисел. Також можна було перебрати три можливі пари двох чисел, і знайти найменшу суму серед таких пар.
Для того, щоб струм передавався між двома сусідніми вимикачами — вони
мають бути в протилежних станах. Тобто, \/
, або
/\
.
Звідси можемо здогадатися, що для того, щоб струм передавався між
всіма вимикачами — потрібно, щоб їхні стани чергувалися. Тобто, існує
всього два можливі варіанти правильного розміщення вимикачів:
\/\/\/...\/\
, або /\/\/\.../\/
.
Для розв’язку задачі достатньо просто обчислити кількість перемикань потрібних, щоб досягти кожного з двох правильних розміщень. А тоді серед них обрати мінімальний.
Найпростіший розв’язок який проходить перші два блоки тестів і набирає 60 балів полягає в тому, щоб для кожного заданого рядка перебрати усі можливі позиції куди можна вставити потрібний символ, і серед усіх таких варіантів вибрати лексикографічно найменший. Для того, щоб реалізувати такий розв’язок треба вміти виконувати операції з рядками: перебирати його символи, вставляти та видаляти символи в рядок, порівнювати їх. Це все можна без проблем робити засобами більшості сучасних мов програмування. Проте, такий розв’язок є надто повільний, щоб отримати 100 балів за задачу.
Для того, щоб розв’язати задачу з повними обмеженнями, треба придумати як для рядка оптимально знаходити місце куди вставити символ, щоб дістати лексикографічно найменший рядок. Цього можна досягнути, якщо вставити символ одразу перед першим таким символом в рядку, який йде пізніше в алфавіті. Якщо ж таких символів немає, треба додати символ в кінець рядка. Правильність такого розв’язку випливає з визначення лексикографічного порядку рядків.
Тому розв’язок наступний:
Для кожного рядка \(s_i\) знайдемо перше входження символу більшого за \(c\), і вставимо символ \(c\) перед ним. Якщо якийсь рядок не містить таких символів, то додамо \(c\) в кінець.
Серед усіх утворених рядків знайдемо лексикографічно найменший по черзі перебираючи усі рядки.
В задачі потрібно порахувати, скільки акумуляторів підійме платформа. Потрібно врахувати, що акумулятори можуть розташовуватися на ній частково, та згодом можуть підіймати інші акумулятори.
Зауважимо наступне. Якщо на платформі вже знаходиться певна конструкція з акумуляторів, які займають проміжок координат [\(l\), \(r\)] — можна ігнорувати всі акумулятори, які будуть опускати поза межами цього проміжку. А для того, щоб підняти акумулятор — потрібно хоча б частково бути під ним.
Тому для розв’язку будемо тримати межі конструкції платформи з акумуляторами (на початку це проміжок \([l=p\), \(r=p]\), оскільки ширина платформи рівна одиниці). Тоді, перевірятимемо кожен акумулятор. Якщо хоча б якась його частина входитиме в проміжок \([l, r]\) — це означатиме, що платформа з іншими акумуляторами зможе його підняти. І оскільки він стане частиною конструкції, що підіймається — потрібно розширити межі конструкції. \([l, r] \rightarrow [min(l, x), max(r, x+1)]\). Залишається лише обчислити кількість таких акумуляторів.
Достатньо перевірити чи \((n - 7 \times i) \mod 4 = 0\) для \(0 \leq i \leq 3\).
B. Дорожня гра з аркушем паперу
Якщо \(n=m\) або \(n \mod 2 = 1\) і \(m \mod 2 = 1\), то гра закінчується в нічию. Адже для будь-якого ходу першого гравця другий може зробити симетричний хід, що принесе таку ж кількість балів. Можна показати, що в іншому випадку, у Зеника завжди існує виграшна стратегія. Наприклад, якщо обидва значення парні, тобто на обидвох сторонах можна провести непарну кількість прямих, то можна показати, що перемагає учасник у кого більша кількість прямих на меншій стороні. Перший учасник може собі це гарантувати, якщо буде проводити прямі по меншій стороні, поки це можливо.
Розглянемо стрічки \(i\) та \(i+1\) для \(1 \leq i \leq n -1\). Подивимося на першу букву, яка відрізняється. Нехай відрізняється символ на позиції j, тоді додамо ребро з \(s[i][j]\) до \(s[i+1][j]\). Тепер подивимося, чи в побудованому орієнтованому графі є цикл. Якщо так, то відповідь No, інакше Yes.
Відповідь не більша 4, адже ми можемо додати по одній точці в кожен кут прямокутника мінімального розміру, в який можливо вмістити усі точки.
Давайте для кожного кута окремо знайдемо, чи можна не додавати точку в цьому куті. Нехай це лівий нижній кут. Знайдемо найлівішу точку, серед таких найнижчу. Далі будемо дивитись на точки зліва направо і якщо точка є найнижчою з розглянутих, то вона повинна бути в маршруті, а також точка, щоб повернути від попередньої точки вниз.
Таким чином для кожного кута, якщо для нього не додавати додаткової точки, можна знайти набір точок, які будуть на маршруті.
Також якщо для декількох кутів ми використаємо однакову точку, то маршрут вийде вироджений, що нам не підходить. Тому можна перебрати, для яких з кутів ми не будемо додавати точки та перевірити, чи маршрути цих кутів не мають спільних точок.
Іншим розв’язком буде навпаки перебирати, які точки на кутах ми додаємо, та перевірити, чи можна побудувати валідний маршрут. В такому випадку потрібно окремо розглянути випадки, коли всі точки у вхідних даних лежать на одній вертикалі чи горизонталі, що не було потрібно у попередньому розв’язку.
Нехай \(a_1, \ldots, a_n\) — послідовність складностей підйому, на основі якої Зеник записав у своєму зошиті послідовність \(c_1, \ldots c_n\). Розглянемо найправішу позицію, де знаходиться мінімальний елемент у послідовності \(a\), і позначимо її \(m_1\). Очевидно, що на цій позиції у послідовності Зеника має бути нуль \(c_{m_1} = 0\), а правіше від неї усі елементи мають бути додатними \(c_{m_1+1} > 0, \ldots, c_{n} > 0\). Отже, ми можемо легко знайти \(m_1\) як позицію найправішого нуля послідовності \(c\).
Якщо нулів немає взагалі, то Зеник припустився помилки у своїх записах, а кількість послідовностей, що їм відповідають, рівна нулю. Інакше запишемо у позиції \(m_1\) мінімально можливе значення \(a_{m_1} = 1\), видалимо \(a_{m_1}\) та \(c_{m_1}\) і перейдемо до меншої підзадачі. Видалення елементу \(a_{m_1}\) результуватиме у зменшення на одиницю усіх елементів \(c\), що знаходяться після позиції \(m_1\). Зауважте, що всі вони після такої операції залишаться невід’ємними.
Далі кожного разу будемо аналогічно знаходити найправішу позицію мінімального елемента \(m_j\) і будемо присвоювати \(a_{m_j}\) мінімально можливе значення. Якщо позиція є більшою за попередню \(m_j > m_{j-1}\), то ми маємо використати значення принаймні на одиницю більше ніж попереднє \(a_{m_j} = a_{m_{j - 1}} + 1\), інакше можемо використати таке ж \(a_{m_j} = a_{m_{j - 1}}\).
Нехай ми успішно знайшли усі позиції \(m_1, \ldots, m_n\). Якщо останнє найбільше використане значення \(a_{m_n}\) є більшим ніж \(k\), то ми не можемо побудувати жодної послідовності \(a\), оскільки щоразу використовували мінімально можливі значення. Інакше ми маємо залишок \(r = k - a_{m_n} \ge 0\) котрий можна розподілити у певний спосіб серед \(n\) позицій послідовності \(a\). Скажімо значення найправішого мінімального елемента \(a_{m_1}\) замість 1 можна обирати більшим, наприклад, 47. Це призведе до автоматичного збільшення на 46 усіх інших елементів \(a\). Легко бачити, що кількість способів розподілити залишок r повністю чи частково між \(n\) позиціями рівна кількості комбінацій з повтореннями з \(n+1\) по \(r\).
Операції пошуку найправішого нуля та зміни елементів послідовності \(c\) можна реалізувати за \(O(\log n)\), наприклад, використавши дерева відрізків. У такий спосіб загальна складність розв’язку буде \(O(n \cdot \log n)\).
Якщо після першого ходу Зеника Марічка не матиме змоги побити жодну фігуру Зеника, то він виграє. Тут показано один з можливих списків ходів для тесту A5 G5 H5.
В іншому випадку, матимемо нічию. Зеник не зможе зробити такий хід, якщо всі три фігури Зеника розташовані на одній вертикалі або горизонталі, король знаходить між турами, при цьому жодні дві фігури не торкаються одна одної аналіз такої позиції.
Також існують винятки, коли Зеник таки перемагає. Аналіз позицій, разом з поясненнями за посиланнями:
Тож можливо було або розглянути усі випадки, або перебрати усі перші ходи та перевірити, чи чорний король не може нічого побити.
G. Гірський спостережний пункт
Спочатку без видалення одного з кабелів для усіх веж знайдемо мінімальні кількості каменюк \(c_1, \ldots, c_n\), що потрібні для побудови. Це можна зробити опрацьовуючи вежі по черзі так, щоб кожного разу для поточної вежі усі, з якими вона з’єднана блакитним кінцем кабелю, вже були опрацьовані раніше. Тоді для поточної вежі ми можемо зафіксувати кількість каменюк і оновити такі кількості для усіх, з якими вона з’єднана жовтим кінцем кабелю.
Для вежі \(k\) розглянемо множину кабелів \(s_k\), що приєднані до неї жовтим кінцем та множину відповідних веж \(t_k\), до яких вони ведуть. Кількість каменюк для вежі \(k\) можна зменшити тільки якщо ми видалимо серед кабелів \(s_k\) той, що веде до вершини з найбільшою кількістю каменюк серед \(t_k\). Назвемо такий кабель важким, а вежу, до якої він веде назвемо батьківською. Кількість каменюк, яку вдасться зекономити на побудові вежі \(k\) видаливши важкий кабель, позначимо \(d_k\). Зауважимо, що \(d_k\) можна легко знайти врахувавши вежі з найбільшою та другою найбільшою кількістю каменюк серед \(t_k\). Також варто окремо врахувати випадки коли множина \(t_k\) порожня або містить тільки одну вежу.
Розглянемо набір кореневих дерев, що утворені важкими кабелями. Очевидно, що є сенс видалити одне з ребер в одному з цих дерев. Нехай ми видаляємо ребро, що веде з вежі \(k\) до її батьківської вежі. Тоді для вежі \(m\) кількість каменюк може змінитись тільки якщо \(m\) знаходиться у піддереві вежі \(k\). Легко бачити, що на побудові вежі \(m\) можна буде зекономити кількість каменюк, що рівна мінімуму зі значень \(d\) на шляху від \(m\) до \(k\).
Далі будемо розглядати усі важкі кабелі у порядку від менших \(d\) до більших. Нехай поточний важкий кабель з’єднує вежу \(k\) з її батьком. Тоді у піддереві вежі \(k\) усі вершини отримають покращення \(d_k\). Нехай розмір піддерева \(k\) рівний \(v_k\), тоді до значення \(d_k \cdot v_k\) можна додати до результату покращення усіх важких кабелів на шляху від \(k\) до кореня. Потім видаляємо поточний важкий кабель і у такий спосіб від’єднуємо вежу \(k\) від піддерева її батька.
Результатом буде сума \(c_1, \ldots, c_n\) мінус максимальне з результатів покращень важких кабелів. Описані операції можна реалізувати, наприклад, використовуючи дерева відрізків побудовані на обході дерев важких кабелів.
Якщо ви тільки починаєте вивчати програмування або незнайомі із змаганнями з програмування, рекомендуємо ознайомитися з нашою системою на сторінці Допомога.
Потрібно написати перевірки для кожної медалі.
Для кожної клітинки без міни порахуємо, скільки в неї є сусідніх клітинок з мінами.
Розглянемо пластинки доміно, де більше число дорівнює \(m\): \((0, m), (1, m), (2, m), \dots, (m, m)\). Сума очок на цих пластинках дорівнює \((0 + m) + (1 + m) + (2 + m) + \dots + (m + m) = (0 + 1 + 2 + \dots + m) + (m + 1) \cdot m = \frac{m(m + 1)}{2} + m(m + 1) = \frac{3m(m+1)}{2}\).
Відповіддю на задачу є сума \(\frac{3m(m+1)}{2}\) за всіма можливими значеннями \(m\) від \(0\) до \(n\).
Складність такого розв’язку — \(O(n)\).
Бонус: як розв’язати задачу за \(O(1)\)?
Спочатку перетворимо координати полів так, щоб кожне поле мало координати \((i, j)\), де \(i\), \(j\) — цілі числа від 0 до 7.
Тоді з поля \((i, j)\) кінь може перейти в поля \((i + 1, j + 2), (i + 1, j - 2), (i - 1, j + 2), (i - 1, j - 2), (i + 2, j + 1), (i + 2, j - 1), (i - 2, j + 1), (i - 2, j - 1)\), якщо він не вийде за межі шахівниці.
Для кожного коня на полі спробуємо всі вісім можливих ходів і
позначимо поля літерою K
.
E. Повторювані числа в матриці
Запишемо всі числа з матриці в один список (vector
у
C++, list
у Python) та посортуємо його.
Якщо число зустрічалося в матриці двічі, то обидва його входження в посортованому списку будуть сусідніми. Пройдемося по посортованому списку та подивимося на всі пари сусідніх елементів. Якщо сусідні елементи однакові, то запишемо цей елемент до відповіді.
Позначимо \(s_i = a_1 + a_2 + \dots + a_i\).
Нехай Марічка з’їсть перших \(i\) цукерок із сумарною смачністю \(a_1 + a_2 + \dots + a_i = s_i\), а Зеник з’їсть цукерки з номерами від \(j\) до \(n\) із сумарною смачністю \(a_j + a_{j+1} + \dots + a_n = s_n - s_{j-1}\). Повинні виконуватися такі дві умови: \(i < j\) та \(s_i \ge s_n - s_{j - 1}\). Друга умова означає, що Зеник не образить Марічку.
Щоб визначити, чи зможе Зеник з’їсти цукерки з номерами від \(j\) до \(n\), треба дізнатися, чи існує таке \(i < j\), що \(s_i \ge s_n - s_{j-1}\).
Для цього будемо ітеруватися індексом \(j\) по масиву \(a\) зліва направо та підтримувати змінну \(m\) — максимальне значення \(s_i\) для \(i < j\). Якщо \(m \ge s_n - s_{j - 1}\), то Зеник може з’їсти цукерки від \(j\) до \(n\) та можна оновити відповідь значенням \(s_n - s_{j - 1}\)
Складність розв’язку — \(O(n)\).
Розв’язок, який обчислює всі значення \(a_2, a_3, \dots, a_n\) та перевіряє знак \(a_n\), набирає частковий бал.
Зробимо спостереження: якщо \(a_0\) і \(a_1\) обидва додатні, то \(a_n\) теж додатне. Аналогічно, якщо вони від’ємні, \(a_n\) — від’ємне.
До розв’язку можна додати оптимізацію, яка використовує це спостереження: як тільки два сусідні елементи \(a_i\) та \(a_{i+1}\) стають обидва однакового знаку, то відразу можна зупинитися та вивести відповідь. Виявляється, цього досить, щоб розв’язати задачу на повний бал.
Доведемо, чому це так. Розглянемо чотири сусідні елементи такі, що в них чергуються знаки. Нехай, без обмеження загальності, \(a_i > 0, a_{i+1} < 0, a_{i+2} > 0, a_{i+3} < 0\).
Виконується \(a_{i+2}=a_i+a_{i+1}\), \(a_{i+3}=a_{i+1}+a_{i+2}\). Отже, \(a_{i+3} = a_i + 2 a_{i+1} < 0\). Звідси \(a_{i+1} < \frac{-a_i}{2}\).
Позаяк \(a_i\) та \(a_{i+1}\) мають різні знаки, то \(|a_{i+2}| = |a_i+a_{i+1}| = |a_i| - |a_{i+1}| = a_i + a_{i+1} < a_i + \frac{-a_i}{2} = \frac{a_i}{2}\). Ми одержали, що \(a_{i+2} < \frac{a_i}{2}\). Це означає, що якщо знаки елементів послідовності чергуються, то значення елементів за модулем за два кроки зменшуються принаймні вдвічі. Звідси випливає, що швидко станеться таке, що сусідні елементи матимуть однаковий знак.
Для розв’язання задачі необхідно просимулювати процес описаний в умові, пройшовши по всіх елементах електричної лінії зліва направо.
Можна довести, що оптимальний для кота розв’язок досягається коли він спочатку стоятиме половину часу, а потім бігтиме другу половину часу. Це пояснюється наступним чином. Нехай кіт доганяє мишу на \(T\) секунд. Тоді, незалежно від чергування режимів, кіт сумарно стоятиме і бігтиме по \(\frac{T}{2}\) секунд. Шукатимемо відповідь у вигляді описаному в першому реченні.
Тоді, існує два випадки:
Кіт почне наздоганяти мишу до того як вона стане в діаметрально протилежну точку кола. Це рівноцінно ситуації, в якій кіт весь час біжить зі швидкістю \(\frac{a}{2}\). Тоді відповідь рівна \(\frac{d}{0.5 \cdot a - b}\). Цей випадок допустимий лише якщо \(0.5 \cdot a > b\).
Поки кіт збирає достатньо енергії, миша стає в діаметрально протилежну точку відносно кота і чекає. Тоді відповідь рівна \(2 \cdot \frac{0.5 \cdot l}{a - b}\).
Відповіддю на задачу буде мінімум серед допустимих випадків.
Для малих n (\(n \le 11\)) можна перебрати всі варіанти за \(O((n-1)!)\).
При \(n > 11\) відповідь завжди буде рівною 3. Це можна довести побудувавши загальні послідовності ходів для випадків \(n = 3 \cdot k\), \(n = 3 \cdot k + 1\) і \(n = 3 \cdot k + 2\).
Нехай в розв’язку \(k\) хороших клітин. Тоді за умовою задачі \(k \ge 0.774 \cdot n \cdot m\). Формулу можна перезаписати як \(k \ge \frac{4}{5} \cdot (1 - \epsilon) \cdot n \cdot m\), де \(\epsilon\) це якесь маленьке число. Множник \(\frac{4}{5}\) означає, що для кожної клітини, в яку покладено міну, всі 4 сусідні клітинки повинні бути заміновані лише нею. Інакше не вийде досягнути бажаної щільності. Множник \((1 - \epsilon)\) дозволяє неефективності замінування на краю поля.
Задачу можна розв’язати використовуючи патерн показаний на зображенні нижче:
Більш формально, міну можна покласти в кожну клітину для якої виконується \(x + 2y \equiv 0 \; (\text{mod } 5)\).
Будемо репрезентувати дороги — як ребра графа, а міста — як вершини. Тоді згідно з умовою граф — це дерево.
Помітимо що шлях буде повністю визначений тим в якому порядку ми йдемо в дітей кожної вершини (вершин, що є сусідами певної вершини та не лежать на шляху від кореня до даної вершини)
Нехай \(dp_v\) — це відповідь на задачу якби Зеник ходив тільки по піддереву вершини \(v\), тобто обхід піддерева який мінімізує втомленість.
\(dp_1\) — буде відповіддю на задачу.
Назвемо суму \(A_i\) в піддереві вершини \(v\) — \(W_i\).
Назвемо кількість вершин в піддереві вершини \(v\) — \(SZ_i\).
Нехай ми знаємо оптимальний порядок, в якому будемо йти з вершини \(v\) в її дітей. Тоді для якоїсь дитини, назвемо її \(to\), нехай \(pref\) — це сума усіх значень \(W_i\) інших дітей вершини \(v\), яких ми обійдемо швидше за \(to\).
Порахуємо скільки втомленості Зеник отримає пройшовши по піддереву \(to\) як частині оптимального обходу піддерева \(v\). Помітимо що до кожного ребра ми додамо вагу \(pref\) якщо порівнювати з оптимальним обходом виключно піддерева \(to\). Іншими словами на інтервалі від заходу до виходу з \(to\) втомленість буде — \(dp_{to}+pref*(SZ_{to}-1)*2\) тобто ми додамо до \(SZ_{to}-1\) ребер \(pref\) по два рази, бо ми пройдемо по кожному ребру в сторону від кореня і потім назад. Для ребер що йдуть безпосередньо в дітей теж можна порахувати таке значення, бо ми знаємо вагу скарбу на вході та на виході в цю вершину.
Тепер залишилось навчитись знаходити оптимальний порядок. Можна уявити піддерева як пари \((w,sz)\) і їх потрібно упорядкувати так, щоб \(\sum_{i<j}w_i*sz_j\) була мінімальною.
Якщо всі \(sz\) дорівнюють \(1\) то це зробити легко, потрібно посортувати їх по вагах. Щоб узагальнити, помітимо, що \(sz\) — цілі і якщо розбити пару \((w,sz)\) на \(sz\) пар по \((\frac{w}{sz},1)\) то вони йтимуть в оптимальному порядку поспіль як один елемент.
Таким чином при розбитті на одиниці оптимальний порядок не зміниться. Тому можна посортувати пари по \(\frac{w}{sz}\) і отримати оптимальний порядок.
Краще не ділити явно, а порівнювати дроби як пари.
Складність \(O(n*log(n))\) (від сортування).
Давайте кожну кульку \(p_i\) з’єднаємо з двома іншими кульками \(q_i\) і \(q_j\) (\(q_j\) така, що значення на ній таке ж, як на \(p_i\)). Отримаємо якусь кількість циклів парного розміру. Надалі розглядатимемо цикли в яких 4 і більше кульок.
Два цикли довжинами \(2n\) і \(2m\) можна розставити за \(n + m\) кроків наступним чином. Позначимо індекси обох циклів як \(i_1, i_2, \ldots, i_n\) та \(j_1, j_2, \ldots, j_m\). Індекси розташовані в порядку обходу циклу. Наприклад, \(p_{i_1} = q_{i_2}\), \(p_{i_2} = q_{i_3}\) і так далі. Спочатку виконаємо \(m\) свапів вигляду \((p_{i_1}, q_{j_k})\) для \(k = 1, 2, \ldots, m\). Далі виконаємо \(n\) свапів вигляду \((p_{i_k}, q_{j_1})\) для \(k = n, n-1, \ldots, 1\).
Якщо кількість циклів була непарною, то залишиться ще один цикл. Нехай його довжина \(2n\). Його можна розв’язати за \(n + 1\) крок. Позначимо індекси циклу як \(i_1, i_2, \ldots, i_n\). Спочатку виконаємо свап \((p_{i_1}, q_{j_1})\). Далі виконаємо \(n\) свапів вигляду \((p_{i_k}, q_{j_1})\) для \(k = n, n-1, \ldots, 1\).
Оберемо якийсь степінь \(k\), нехай це буде — \(b\).
Тоді будь-яке число \(x\) — можна репрезентувати як \(m \cdot k^b+z\), де \(0 \le m\) і \(0 \le z < k^b\).
Нехай \(F(x) = \sum_{p=0}^{\infty} \lfloor \frac{x}{k^p} \rfloor\) (функція з умови).
Тоді \(F(m \cdot k^b+z) = F(m \cdot k^b) + F(z)\).
Розіб’ємо числа від \(0\) до \(n\) на блоки розміру \(k^b\) такі, що \((k^b+\frac{n}{k^b})\) – мінімальне. При \(b = \frac{log(n)}{2 \cdot log(k)}\) заокругленому до найближчого цілого сума не перевищуватиме \(2 \cdot (n \cdot k)^{\frac{1}{2}}\), оскільки найбільше з двох чисел не перевищуватиме \((n \cdot k)^{\frac{1}{2}}\).
Суфікс, який не потрапить в жоден блок, рахуватимемо окремо, його довжина буде менше \(k^b\).
Тоді для кожного блоку, межі якого повністю лежать від \(0\) до \(n\) включно, порахуємо його \(F(B \cdot k^b)\) де \(B\) — номер блоку (нумерація від 0). І для чисел \(z\) від \(0\) до \(k^b\) виключно порахуємо \(F(z)\). Тоді будь-яке число буде складатись з \(F(B \cdot k^b)\) + \(F(z)\).
Для кожного запиту нам потрібно рахувати кількість пар \((B,z)\) таких що \(F(B \cdot k^b+z)=g \: (mod \: s)\). Перебиратимемо \(B\) і додаватимемо кількість таких \(z\) що \(F(B \cdot k^b)+F(z)=g \: (mod \: s)\). Це можна зробити тримаючи в масиві кількість кожної остачі та перераховуючи для кожного запиту.
Якщо порахувати усі \(F\) до обробки запитів, а при обробці брати лише модулі то складність буде: \(O(\sqrt{nk} \cdot (\log(n)+q))\).
Кожному коню необхідно 4 підкови, отже сумарно нам необхідно \(4 \cdot n\) підков.
Обмеження задачі дозволють перебрати кількість ящиків від 1 до \(4 \cdot n\) та перевірити, чи цієї кількості достатньо щоб підкувати всіх коней.
Також найменшу кількість ящиків можна було знайти формулою \(m = \lceil \frac{4 \cdot n}{k} \rceil\) — ділення \(4 \cdot n\) на \(k\) із заокругленням догори.
Знайшовши \(m\) можна порахувати відповідь за формулою \(m \cdot c\).
Код розв’язку мовою C++ з перебором \(m\)
Нехай \(s\) — сума поживностей трави на всьому пасовищі.
Зафіксуємо межу поділу пасовища. Нехай сума в лівій частині дорівнює \(p\). Тоді сума в правій частині буде \(s - p\). Відповідь для такого поділу буде \(p - (s - p) = 2 \cdot p - s\).
Отже, можна перебрати межу зліва направа, підтримуючи змінну \(p\). Коли пересуваємо паркан на одну ділянку праворуч, то до лівої частини долучається нова ділянка і до \(p\) додається значення поживності трави на цій ділянці.
Задача полягає в тому, щоб знайти, на яку найменшу кількість груп треба поділити коней, так аби можна було їх впорядкувати. Позначимо цю кількість \(m\). Якщо \(m \le k\), відповідь — так, інакше — ні.
Розглянемо двох коней \(p_i\) та \(p_{i+1}\), що стоять поруч.
Якщо \(p_{i+1} = p_i + 1\), то ці коні після впорядкування також стоятимуть поруч, тому нема сенсу їх розділяти на різні групи.
Якщо ж \(p_{i+1} \ne p_i + 1\), коні вже не стоятимуть поруч, тому їх обов’язково треба розділити на різні групи.
Отже, щоб знайти \(m\), треба порахувати кількість таких позицій \(i\), що \(p_{i+1} \ne p_i + 1\), та додати до цієї кількості одиницю (якщо коні вже стоять у правильному порядку, то \(m=1\)).
Переформулюємо задачу. Задано рядок \(s\) з 0
і 1
.
Запит першого типу присвоює першим \(i\) символам задане значення, а запит
другого типу — знайти символ в \(i\)-й
позиції.
У цій задачі будемо підтримувати проміжки однакових значень у рядку \(s\).
Наприклад, \(s =
\,\)000011100111100000
. Перший проміжок закінчується
в позиції \(4\) та складається із
символів 0
. Позначимо цей проміжок (\(4\), 0
). Другий проміжок
закінчується в позиції \(7\) та
складається із символів 1
. Позначимо його (\(7\), 1
). Усі проміжки для
рядка \(s\): (\(4\), 0
), (\(7\), 1
), (\(9\), 0
), (\(13\), 1
), (\(18\), 0
).
Якщо надійде запит присвоїти першим \(8\) символам рядка значення 1
,
рядок перетвориться на 111111110111100000
. Проміжки для
нового рядка: (\(8\), 1
),
(\(9\), 0
), (\(13\), 1
), (\(18\), 0
).
Як видно з прикладу, запит першого типу видалить деякі проміжки з початку, та вставить один проміжок замість них.
Розгляньмо запит другого типу. Нехай потрібно знайти символ на \(i\)-ій позиції. Для цього треба знайти
проміжок, який містить цю позицію. Це проміжок, що закінчується в
позиції \(\ge i\), у якого позиція
закінчення найменша. У нашому прикладі для \(i
= 11\) це проміжок (\(13\),
1
).
Щоб розв’язати задачу, будемо підтримувати згадані проміжки в порядку
справа наліво (у спадному порядку позицій закінчення проміжків). У
C++
можна використати
vector<pair<int, char>>
.
Для запиту першого типу треба видалити деякі проміжки з кінця
(pop_back
) та вставити в кінець
(push_back
).
Щоб відповісти на запит другого типу, знайдемо потрібний проміжок двійковим пошуком. Якщо ви не знайомі із цим алгоритмом, наполегливо рекомендуємо прослухати відеолекцію на YouTube каналі Алготестера.
Тепер оцінимо складність розв’язку.
Перед усіма запитами є \(O(n)\)
проміжків. Для кожного запиту першого типу додасться один новий
проміжок. Тому загальна кількість усіх доданих проміжків упродовж роботи
алгоритму — \(O(n + q)\). А скільки
може бути видалень проміжків (pop_back
)? Спершу може
здатися, що оскільки всього є \(O(n +
q)\) проміжків, то для кожного запиту першого типу буде \(O(n + q)\). Однак кожен проміжок буде
видалено не більше ніж один раз. Тому загальна кількість видалень також
\(O(n + q)\).
Для кожного запиту другого типу ми виконуємо двійковий пошук за \(O(\log (n + q))\).
Загальна складність: \(O(n + q + q \log (n + q)) = O(n + q \log (n + q))\).
Розв’яжемо задачу для \(n = 1\). Порахуємо для кожної ділянки, який у ній утворюється рівень шуму.
Коня з ділянки \(j\) чутно на ділянці \(y\) (\(j \le y\)) з гучністю \(\max(0, a_{1, j} - (y - j))\). Вираз \(a_{1, j} - (y - j) = (a_{1, j} + j) - y\) містить доданок \(y\), який не залежить від того якого коня вибрали, та доданок \(a_{0, j} + j\), що залежить лише від коня.
Будемо ітеруватись зліва направо по клітинках і пам’ятати максимальне значення \(a_{1, j} + j\) по усіх конях зліва. Віднявши від цього максимального значення \(y\), отримаємо рівень шуму який утворюють коні зліва. Аналогічно для кожної клітинки порахуємо який шум утворюється справа. Отже, шум який утворюють коні в цій клітинці рівний більшому зі значень шумів зліва та справа. Відповідно маючи рівень шуму в усіх клітинках, ми можемо знайти мінімальне значення шуму.
Якщо ж \(n \ne 1\) тоді ми поле можемо розділити на 4 чверті відносно ділянки \((x, y)\): ліву нижню, ліву верхню, праву нижню та праву верхню. Розглянемо лише одну чверть, де коні стоять у таких клітинках \((i, j)\) що \(i \le x\) та \(j \le y\).
Серед коней що мають \(i \le x\) та \(j \le y\) потрібно знайти найбільше значення \(a_{i, j} - (x - i) - (y - j) = (a_{i, j} + i + j) - (x + y)\). Тут аналогічно є доданок, що залежить лише від ділянки і доданок, що залежить лише від коня. Враховуючи це, можемо зробити аналогічно до \(n = 1\), тобто порахувати максимальне значення \(a_{i, j} + i + j\) по всіх конях що \(i \le x\) та \(j \le y\) — назвемо це значення \(mx(x, y)\). Значення \(mx(x, y)\) рівне \(\max(mx(x - 1, y), mx(x, y - 1), a_{x, y} + x + y)\).
Так ми врахували коней, що пасуться лише в одній чверті відносно ділянки \((x, y)\). Щоб урахувати всі 4 чверті, 4 рази повернемо матрицю на 90 градусів.
Розв’яжемо задачу окремо для паліндромів парної та непарної довжин.
Якщо в нас є паліндром \(p\) довжини
\(x > 1\), тоді якщо відкинути
перший і останній символ такого паліндрому, то отримаємо паліндром
довжини \(x - 2\). Напркилад, якщо
\(p\) = abbcbba
, то
відкинувши перший і останній символи отримаємо bbcbb
, що
теж є паліндромом. Ми так можемо відкидати символи, поки їх хоча б 3. Те
що залишилося після такого процесу, назвемо центром паліндрома. Для
непархних паліндромів, центр це один символ, для парних — нуль.
Розв’яжемо задачу для непарних паліндромів. Будемо перебирати символи зліва направо і пробувати покращити ними відповідь. Початково відповідь для першого символу 1. Нехай ми розглянули перші \(i - 1\) символи, як центри і найкраща відповідь це \(len\). Тоді для центру \(i\) нам цікаво чи можемо ми покращити відповідь. Зробимо запит непарного паліндрому з центром в \(i\)-тому символі і довжиною \(len + 2\). Якщо ми отримуємо відповідь, що такий підрядок є паліндромом, то оновимо відповідь і запитаємо чи є паліндромом рядок з центром в символі \(i\) і довжиною \(len + 4\). Будемо пробувати збільшувати довжину, поки наш запит не вилазить за межі рядка і ми отримали ствердну відповідь на попереднє запитання.
Порахуємо кількість запитів, яку ми використали. Кожен раз коли ми отримали ствердну відповідь, то розмір найбільшого паліндрому збільшується на 2, тобто це буде зроблено не більше ніж \(\frac{n}{2}\) разів. Для кожного центру, коли ми отримуємо відповідь 0, то перестаємо робити запити з цим центром, відповідно таких запитів буде не більше ніж \(n\).
Для парних паліндромів розв’яжемо аналогічно, тому загальна кількість запитів буде не більшою ніж \(3 \cdot n\).
Переформулюємо задачу наступним чином: Для всіх перестановок порахуємо кількість разів, коли елемент є максимумом на своєму префіксі.
Змінимо порядок сумування, тепер нам потрібно для кожної позициї порахувати у скількох перестановках елемент на цій позиції є максимумом на префіксі.
Розглянемо позицію \(i\). Назвемо перестановку хорошою, якщо елемент позиції \(i\) є максимумом на префіксі. Спочатку погрупуємо перестановки по тому, які елементи знаходяться на префіксі довжини \(i\). Таких груп буде \(C_n^i\). Для кожної групи порахуємо скільки є хороших перестановок.
Для групи, ми знаємо які елементи є на префіксі на префіксі довжини \(i\). Для хороших перестановок максимум з них буде на позиції \(i\). Всі інші елементи можна поставити в довільному порядку. Кількість способів розмістити елементи на префіксі є \((i - 1)!\) способів, а на суфіксі — \((n - i)!\). Відповідно в групі буде \((i - 1)! \cdot (n - i)!\) хороших перестановок.
Загальна формула виглядатиме так: \(\sum_{i = 1}^{n} C_n^i \cdot (i - 1)! \cdot (n - i)!\).
Можна або знайти суму і мінімум, або посортувати усі вартості та додати всі крім найменшої.
Поставимо значення 1, 2, \(\dots\), \(\left \lceil{\frac{n}{2}}\right \rceil\) в такому порядку на непарні позиції, та значення \(\left \lceil{\frac{n}{2}}\right \rceil + 1\), \(\dots\), \(n\) на парні. Наприклад, для \(n=7\) вийде [1, 5, 2, 6, 3, 7, 4].
У такій побудові \(a_{i+2}=a_i+1\), а отже \(a_{i+1}+a_{i+2}=a_i+a_{i+1}+1\). Тобто усі значення \(a_i+a_{i+1}\) будуть рівні \(x, x+1, \dots, x+n-2\), де \(x=a_1+a_2\).
Всі такі значення дають різні остачі при діленні на \(n\).
Якщо в рядку \(s\) є 1 чи 2 різні символи, то не вийде використати менше, а отже можна взяти \(t=s\).
Далі якщо взяти \(t\)=abcabcab...
, то в \(t\) немає підрядків паліндромів крім
підрядків з 1 символа. Отже, \(t\) буде
палідромно меншим за \(s\).
Можливо показати, що неможливо, щоб в \(t\) було менше ніж 3 різних символів, якщо
розглянути підрядок \(s\) вигляду
ab...bc
.
Існує не більше 24 різних маршрутів. Це так, бо більшість поворотів буде відбуватись в куті поля (якщо видаляти вже відвідані клітинки), а отже буде тільки 1 варіант куди іти далі.
Тому можливо згенерувати повним перебором усі маршрути, подивитись, які з них завершуються в потрібній клітинці та вибрати з них найдовший.
E. Перестановка з двох масивів
Розглянемо кожен біт окремо. Подивимось скільки в результаті повинно бути чисел, в яких цей біт 1 і скільки таких, в яких 0. Позначимо це \(c_0\) та \(c_1\). Якщо \(c_0 \ne c_1\), то існує не більше одного варіанту, яким цей біт може бути в \(x\) та \(y\). Це так тому, що \(n\) та \(m\) непарні. Розглянемо випадок, коли \(c_0=c_1\). Таке можливо лише якщо \(n+m\) ділиться на \(2^{bit+1}\), а також якщо всі елементи перестановки проксорити з \(2^{bit}\), то це теж буде перестановкою. Тобто в цьому випадку можливими є 2 варіанти, якими значеннями можуть бути біти в \(x\) та \(y\), обидва нам або одночасно підходять, або не підходять. Спробуємо будь-який з них, перевіримо чи в результаті вийшла перестановка. Якщо так, то відповідь рівна \(2^k\), де \(k\) — найбільший степінь 2, що ділить \(n+m\).
Іншим розв’язком буде подивитись на xor усіх чисел. З цього можливо знайти \(x\ xor\ y\). Замінимо всі значення другого масиву \(b_i := b_i\ xor \ (x\ xor\ y)\). Далі обидва масиви потрібно ксорити з \(x\), подивимось чи немає однакових значень. Можна перебрати, яке значення буде в результаті 0 та префіксним деревом перевірити, чи всі решта чисел виходять менші \(n+m\). Або також можна для кожного значення згенерувати проміжки \(x\), коли значення будуть менші \(n+m\).
Розглянемо 3 вежі \(x_1 < x_2 < x_3\) та \(y_2 \ge min(y_1, y_3)\). Використовувати кабель між 1 і 3 вежею не вигідно: або ми не можемо його провести або вигідніше його замінити на менші кабелі, бо \(dist(1, 3) > dist(1, 2)\) та \(dist(1, 3) > dist(2, 3)\).
Тепер нас цікавлять тільки такі пари веж, що всі вежі між ними менші за обидві крайні. Зрозуміло, що такий кабель не буде перетинатись з іншими вежами. А також таких пар веж є \(O(n)\), згенерувати їх можна, якщо розглядати вежі зліва направо та підтримувати спадний стек.
Тож згенеруємо всі такі пари та знайдемо найменший каркас алгоритмом Крускала.
Розглянемо останню операцію, нехай вона \(x \to y\). Нам потрібно, щоб для конкретного біта, в \(x\) цей біт був 1, а в \(y\) 0.
Припустимо, що ми отримали \(y\) використовуючи операцію \(y=y_1 \to y_2\). Тоді \(x \to y = x \to (y_1 \to y_2) = x \to (!y_1\ |\ y_2)\). Якщо ж з іншого боку залишити \(y_2\) для останньої операції і зробити операцію \(y_1 \to x\), то вийде \((!y_1\ |\ x) \to y_2\). Таким чином ми отримаємо не гірше значення і зліва і справа — зліва буде не менше 1, а справа не менше 0. З цього можна зробити висновок, що \(y\) має бути одним з оригінальних чисел набору. Переберемо його і залишимо тільки ті біти, де 0.
Ми можемо отримати \(x =\ !a_1\ |\ !a_2\ |\ \dots\ |\ !a_{i-1}\ |\ !a_{i+1}\ |\ \dots\ |\ !a_n\ |\ a_i\), тобто усі значення крім одного з запереченням. Щоб в такому значенні був біт 0 потрібно, щоб у всіх крім одного значеннях, цей біт був 1, а в одному 0.
Назвемо біт унікальним, якщо він рівний 0 в рівно одному значенню. Назвемо значення унікальним, якщо воно містить хоча б один унікальний біт. Якщо існує не унікальне значення, то можна отримати \(x=2^k-1\), якщо його обрати як значення без заперечення. Якщо \(n>k+1\), то точно існує неунікальне значення, а отже \(x=2^k-1\).
Інакше все одно можна розглядати лише значення \(x =\ !a_1\ |\ !a_2\ |\ \dots\ |\ !a_{i-1}\ |\ !a_{i+1}\ |\ \dots\ |\ !a_n\ |\ a_i\). Це так тому, що які б операції ми не робили, унікальні біти одного з початкових значень залишаться 0. А розглядаючи тільки такий вигляд в нас вийдуть всі інші біти 1.
Тому для кожного запиту, якщо \(r - l + 1 > k+1\), то відповідь рівна мінімальній кількості одиничних бітів на проміжку. Якщо \(r-l+1 \le k+1\), то можна перебрати, яке значення \(y\) та яке значення беремо в \(x\) без заперечення. Тобто відповідь на запит можна знайти за \(O(k^2)\).
В цій задачі можна просимулювати процес, описаний в умові, або ж посортувати масив і за один прохід знайти відповідь.
Неважко побачити, що, оскільки розмір однієї зі сторін диванів рівний \(n-1\), то не можна одночасно помістити більше одного горизонтального та більше одного вертикального дивана. Тому потрібно розглянути декілька випадків:
Усі дивани горизонтальні. Для цього випадку потрібно лише перевірити, в яку кількість рядків може поміститись диван.
Усі дивани вертикальні (аналогічно).
Один диван горизонтальний, усі інші — вертикальні. Для цього можна перебрати, куди буде поставлено горизонтальний диван, після чого задача зводиться до попередньої.
Один диван вертикальний, усі інші — горизонтальні (аналогічно).
Знайдемо суму усіх заданих чисел, окрім перших \(min(n, 47)\), та позначимо цю суму як \(s\). Усі інші числа послідовними операціями ділення зведемо до 1. Далі послідовно опрацюємо кожну з одиниць, окрім однієї, наступним чином: знайдемо наймолодший нульовий біт у \(s\), та послідовними операціями множення перетворимо поточну одиницю на цей біт. Таким чином, використовуючи \(min(n, 47)-1\) одиниць, усі нульові біти в \(s\) будуть покриті, отже сума перетвориться на \(2^k-1\). Оскільки одну з \(min(n, 47)\) одиниць ми залишили, загальна сума буде степенем двійки.
Неважко побачити, що потрібна кількість операцій буде значно меншою за \(2 \cdot 10^5\).
D. Злиття послідовності і перестановки
Якщо всі числа в \(a\) однакові, то відповідь -1.
Інакше, знайдемо усі пари сусідніх елементів в \(a\), які є однаковими. Таких пар буде не більше ніж \(n-2\). Це означає, що можна послідовно для кожної із пар знаходити число (серед чисел від 1 до \(n\)), яке ще не було використано і яке не рівне їх значенню. Таке значення знайдеться, оскільки завжди буде хоча б 2 числа, які залишились.
Усі числа які не були вставлені всередину послідовності \(a\) можна розмісити вкінці. Оскільки чисел залишиться хоча б 2, то точно знайдеться одне, яке є іншим ніж останнє число в послідовності.
E. Перестановки в перестановці
Нехай потрібно перемістити значення \(val\) з позиції \(from\) на позицію \(to\) за мінімальну кількість кроків. Спершу припустимо що \(to < from\), тобто число \(val\) необхідно посунути ліворуч на \(from - to\) позицій. Це означає, що треба \(from-to\) разів поміняти елемент \(val\) з елементом котрий знаходиться ліворуч від нього.
Перепишемо умову того що можемо поміняти місцями два сусідні елементи: \(p_{i-1} \le p_i + d\). Виходить, що умовою того що, можна поміняти елемент ліворуч від \(val\) з \(val\) є наступна: \(p_{i-1} \le val + d\), де \(i\) — поточна позиція числа \(val\), а \(i\) — його позиція. З цього випливає, що необхідно вибрати \(from - to\) найближчих до \(val\) елементів перестановки котрі знаходяться ліворуч від \(val\) і сунути кожного з них праворуч, поки не поміняємо їх місцями з \(val\), в порядку справа наліво. Це завжди можна зробити, тому що якщо існує якийсь елемент \(x\), такий що \(x > val + d\), то інший елемент \(y\), такий що знаходиться ліворуч від \(x\) і \(y \le val + d\) завжди можна буде поміняти місцями з \(x\), тому що \(val < x - d\), а \(y \le val + d < x - d + d = x < x + d\).
Тому відповідь буде рівна \(from \cdot (from - to) - \frac{(from - to) \cdot (from - to - 1)}{2} - s\), де \(s\) — це сума індексів \(from-to\) найближчих до \(from\) елементів ліворуч, що не перевищують \(val + d\). Цю суму можна знайти спуском по дереву відрізків, або двійковим пошуком разом з фенвіком, якщо влаштувати скануючу пряму по значеннях елементів.
Випадок \(to > from\) можна розглянути аналогічно. В цьому випадку умовою буде \(p_{i+1} \ge p_i - d\), тому треба буде знаходити найближчі \(to-from\) елементів праворуч від \(from\), які більші або рівні за \(val - d\). Це така сама задача як і попередня, якщо розвернути перестановку і зробити заміну: \(p'_i = n - p_i - 1\).
Розв’яжемо задачу для фіксованого \(c\). Для цього достатньо знайти компоненти зв’язаності по усіх білих вершинах, між якими є шлях із не більше ніж \(c\) чорних. Запустимо BFS одночасно з усіх білих вершин і знайдемо для кожної вершини найменшу відстань до неї \(d_i\) та індекс найближчої білої вершини \(p_i\). Якщо для якогось ребра між \(u\) та \(v\) виконується що \(d_u + d_v \le c\), то об’єднаємо \(p_u\) та \(p_v\) у в одну множину, використовуючи структуру даних "система неперетинних множин". Можна показати, що після такого процесу, усі пари білих вершин, між якими є шлях із не більше ніж \(c\) чорних, будуть об’єднані в одну множину.
Для того, аби відповідати на запити із різними значеннями \(c\), достатньо посортувати їх по \(k_i\), а також посортувати список подій об’єднання за значення \(d_u + d_v\). Перебираючи події, можна рухатись вказівником і виконувати потрібні об’єднання, а після цього відповідати на поточний запит використовуючи СНМ.
G. Найнижчий найвищий спільний предок
Для кожного кольору порахуємо розмір компоненти — кількість вершин, пофарбованих у цей колір. Зауважмо, що таких різних розмірів буде не більше ніж \(\sqrt{2n}\), оскільки їх сума до \(n\).
Знайдемо для кожного розміру LCA (lowest common ancestor) усіх вершин усіх кольорів з компонентами такого розміру. Якщо хоча б одна із цих компонент буде використана у відповіді, то загальне LCA буде не нижче ніж ця вершина, за винятком випадку коли відповідь — це одна компонента, який можна опрацювати окремо. Отже, для кожного розміру знайдемо LCA усіх вершин та кількість компонент такого розміру; самі компоненти стають однаковими.
Зауважмо, що для того, аби знайти LCA для довільного набору компонент, достатньо знати вершину з найменшим та найбільшим часом входження DFS, і LCA між ними буде співпадати із загальним LCA.
Отже, посортуємо усі розміри компонент по часу входження в LCA, і зробимо динамічне програмування зі станом \([size][sum]\), де \(size\) — поточний розмір компонент, \(sum\) — поточна загальна сума розмірів вибраних компонент, а результат — мінімальний час входження DFS по LCA усіх вибраних компонент. При переході нам потрібно перебрати, скільки компонент поточного розміру попадуть у відповідь. Для того, аби ефективно виконати цей перехід, можна окремо опрацювати значення \(sum\) по усіх остачах від ділення на \(size\), і використати алгоритм знаходження мінімуму на черзі для обчислення результату переходу динамічного програмування. Після довільного переходу ми можемо вирішити, що він останній, і оскільки ми знаємо LCA із найменшим часом входу DFS, а поточний \(size\) має LCA є з найбільшим часом входу (оскільки вони посортовані), то LCA між ними і буде кандидатом на відповідь для поточного \(sum\).
Загальна складність: \(O(n\sqrt{n})\)
Вам потрібно зчитати числа \(n, t\), а також n чисел \(a_{і}\). Тоді потрібно порахувати \(S = |a_0 - a_1| + |a_1 - a_2| + ... + |a_{n-2} - a_{n-1}|\). Відповідь буде \(t \cdot S\), її і виведемо.
Нехай в нас є деяка найкраща послідовність \(S_{ijk} = |a_i - b_j| + |a_{i+1} - b_{j+1}| + ... + |a_{i+k-1} - b_{j+k-1}|\) для певних \(i, j > 0\). Тоді зауважимо, що \(S^{\prime} = |a_{i-1} - b_{j-1}| + S_{ijk} \geq S_{ijk}\) також задовольняє умові і є не меншою ніж \(S_{ijk}\). Цей процес ми можемо повторювати доти доки одне з чисел \(i, j\) стане нулем. А отже існує найкраща послідовність де \(i=0\) або \(j=0\). Використаємо цей факт, щоб зробити два перебори. Перший по \(i\) де \(j=0\) (а також всеможливих \(k\)). Другий навпаки. Оберемо найкраще значення яке вдалось отримати. Складність \(O(N^2)\) де \(N\) довжина довшої з послідовностей.
Нормалізуємо всі вхідні рядки: будемо додавати в "нормалізованих" рядок символ за символом. Якщо два останні символи однакові — видаляємо їх. Складність такої нормалізації \(O(|s|)\). Після нормалізації рядок матиме один із двох видів: \(474747474....\) або \(747474....\).
Розглянемо що станеться, якщо з’єднати два такі рядки \(S_x\) і \(S_y\). Є два варіанти:
1. Якщо останній символ \(S_x\) та перший символ \(S_y\) різні, то стрічки просто з’єднаються: \(4747474...7+47474747...\). Довжина з’єднання дорівнюватиме сумі довжин \(S_x\) та \(S_y\).
2. Якщо останній символ \(S_x\) та перший символ \(S_y\) однакові, то після з’єднання вони знищаться. Наступні символи теж будуть однакові і знищаться. Це триватиме доки однин із рядків не стане порожнім.
\[4747474...4747+7474747... \rightarrow 4747474...474\textbf{77}474747... \rightarrow 4747474...47\textbf{44}74747... \rightarrow ...\]
Довжина з’єднання в цьому випадку дорівнюватиме абсолютній різниці довжин двох рядків.
Давайте окремо перевіримо, чи існує виграшна стратегія у першого гравця та чи існує виграшна стратегія у другого гравця. Якщо у жодного гравця немає виграшної стратегії, то гра завершиться нічиєю.
Спершу перевіримо, чи зможе перемогти другий гравець. Якщо він ходить вліво чи вправо, то перший гравець завжди може відмінити цей хід, якщо походить в протилежному напрямку. Отже, другий гравець в будь-якому разі буде вимушений ходити вгору. Значить, для першого гравця задача не програти, якщо він знає, що другий гравець завжди ходить вгору. Тобто перший гравець програє лише, якщо як би він не ходив, в результаті він попаде в стан, де більше не може робити хід. Аналогічно, він не програє, якщо заставить другого попасти в стан, де той не зможе походити вверх – найвища точка будь-якої вежі.
Тоді якщо першому достатньо бути на висоті \(х\) вежі \(k\), то йому також вигідно бути на висоті \(x-2\) цієї ж вежі або на висоті \(x-1\) вежі \(k-1\) або вежі \(k+1\).
Згенеруємо усі такі стани алгоритмом схожим на алгоритм Дейкстри. Для вежі \(k\) та парності \(c\), будемо знаходити такий найбільший \(2x+c\), що на такій висоті вигідно перебувати першому гравцю.
Далі, якщо ми хочемо знайти, чи зможе перемогти перший, то він змушений першим ходом ходити вгору. Далі задача залишається такою ж, адже гравці міняються ролями.
Спочатку згенеруємо всі щасливі числа з проміжку \([L, R]\). Загалом їх буде не більше, ніж \(T = 2^{19} - 2\), адже щасливих чисел довжини \(x\) є рівно \(2^x\).
Зафіксуємо число \(B\). Погрупуємо всі числа за остачами при діленні на \(2^B\) (значення останніх B бітів числа). Тепер цікаві пари можуть знаходитися в групах з остачами \(G_1, G_2\) лише якщо \(G_1 AND G_2 = 0\). Всього таких пар груп є \(O(3^B)\) адже для групи з остачею \(G\) підходять лише групи з підмасками числа \((2^B - 1 - G)\).
Позаяк щасливі числа мають досить випадкові двійкові представлення, можна побачити, що кількість чисел в кожній групі буде практично однаковою, тому можемо для кожної пари груп перебрати всі варіанти вибору двох чисел з них. Таким чином складність буде \(O(3^B * (T / 2^B)^2) = O(T^2 / (4/3)^B)\), тому виберемо досить велике \(B\), наприклад \(B = 16\).
Альтернативний розв’язок. Побудуємо префіксне дерево по двійкових представленнях всіх щасливих чисел. Тепер для кожного числа \(x\) будемо шукати всі числа \(y > x\) та \(y AND x = 0\). Для цього будемо робити пошук, починаючи з кореня префіксного дерева. Якщо зараз стоїмо у вершині \(v\), а черговий біт у числі \(х\) встановлений, то в \(y\) він має бути відсутній, тому маємо лише один перехід. Якщо ж цей біт у \(х\) відсутній, то спустимося до обох синів \(v\) (якщо такі існують), та шукатимемо \(y\) в них обох. З огляду на випадковість двійкового представлення щасливих чисел, такий розв’язок достатньо швидкий для заданих обмежень.
Спершу покажемо, що завжди існує дерево бамбук, яке схоже на будь-яке оригінальне дерево. Бамбук – дерево, в якому всі вершини розташовані в ряд та кожна вершина з’єднана ребром зі своїми сусідами.
Доведемо це методом математичної індукції. Розглянемо найбільше ребро, видалимо його, таким чином розділимо дерево на 2 частини. Зауважимо, що ми можемо отримати схоже дерево бамбук для обох частин, а потім з’єднати їх видаленим ребром.
Повернемось до оригінальної задачі. Будемо додавати вершини по одній та будувати дерево бамбук. Запитаємо максимальну вагу ребра на шляху від нової вершини до центральної в бамбуку. Якщо таке значення ваги вже було раніше, то ми знаємо, з якої сторони від центральної вершини, повинна знаходитись нова вершина. Припустимо такого значення не було. Нехай це значення \(w\). Знайдемо перше ребро справа від центральної вершини з вагою більшою за \(w\). Вставимо нову вершину в середину цього ребра. Якщо такого ребра не існує, то вставимо нову вершину в кінець масиву. Можна показати, що таке дерево буде схожим на оригінальне. Тобто при додаванні нової вершини ми можемо використати двійковий пошук, щоб знайти куди можливо її вставити.
Також існує рандомізований розв’язок. Візьмемо випадкову вершину, знайдемо ваги від неї до всіх інших вершин. Поділимо всі вершини на групи з однаковим значенням, розв’яжемо задачу для кожної групи окремо, після цього зробимо бамбук, в якому впорядкуємо групи за значенням.
Скажемо, що кожна намистинка вказує найближчу намистинку такого ж кольору. Якщо \(d_i > 0\), то намистинка на позиції \(i\) може вказувати або на намистинку \(i-d_i\) або на намистинку \(i+d_i\).
Для того, щоб потрібне намисто існувало необхідно і достатньо, щоб виконувались умови:
Жодна намистинка не може вказувати на намистинку з більшим значенням \(d\) чи значенням 0.
Якщо намистинка \(x\) вказує вправо на намистинку \(y\), то намистинка \(y\) може вказувати вліво лише у випадку, якщо \(d_x=d_y\), тобто намистинка \(y\) вказує на намистинку \(x\)(і навпаки).
Не може існувати двох намистинок, які вказується вправо на ту ж намистинку(і навпаки).
Розв’яжемо задачу алгоритмом 2-SAT. Для кожної намистинки зробимо змінну, яка рівна true, якщо намистинка вказує вправо та false, якщо вліво.
Перша умова вказує, що деякі змінні не можуть приймати значення true чи false. Щоб задовольнити другу умову потрібно додати \(O(n)\) обмежень задачі 2-SAT.
Для третьої умови, нехай намистинки \(x_1, x_2, \dots, x_k\) усі вказують вліво на намистинку \(y\). Тоді нам потрібно додати обмеження \(x_i | x_j\) для усіх \(i \ne j\), яких може бути \(O(n^2)\). Подивимось, які ребра ми додаємо в граф для розв’язку задачі: це будуть усі ребра \(!x_i \to x_j\) для \(i \ne j\). Тобто нам потрібно, щоб з кожного \(!x_i\) були досяжні усі інші \(x_j\) крім \(x_i\). Додамо додаткові вершини \(p_i\), з якої досяжні усі змінні на префіксі \(x_1, x_2, \dots, x_i\). Для цього додамо по 2 ребра \(p_i \to p_{i-1}\) та \(p_i \to x_i\). Аналогічно додамо додаткові вершини \(s_i\), які відповідають за суфікси. Після цього ми можемо додати 2 ребра \(!x_i \to p_{i-1}\) та \(!x_i \to s_{i+1}\). Таким чином ми отримали граф з такими ж властивостями, як в графа 2-SAT, але в ньому O(n) вершин та ребер.
A. Найбільша зростаюча підпослідовність
Завдання задачі — порахувати, скільки символів треба видалити в підрядку, аби він перетворився у паліндром.
Нехай \(\text{dp}[l][r]\) — відповідь на задачу для підвідрізка від \(l\)-го до \(r\)-го символа.
Початкові стани: для проміжка довжини \(1\) маємо \(\text{dp}[i][i] = 0\), а для проміжка довжини \(2\) \(\text{dp}[i][i + 1]\) дорівнює \(0\) або \(1\).
Для підрядків з довжиною хоча б \(3\) можемо розглянути крайні елементи. Якщо вони рівні (\(s_l = s_r\)), тоді ми можемо визначити що \(\text{dp}[l][r] = \text{dp}[l + 1][r - 1]\). У випадку коли символи різні (\(s_l \ne s_r\)), то треба видалити один із цих символів тобто \(\text{dp}[l][r] = \min (\text{dp}[l][r - 1], \text{dp}[l + 1][r]) + 1\).
Перш за все нам потрібно перевірити першу умову, що числа зростають.
Якщо це не так, тоді ми знаємо що відповідь — No
..
Розглянемо таку динаміку: \(\text{dp}[s] =\) true/false — чи можна отримати суму чисел \(s\) використовуючи лише розглянуті числа.
Коли ми розглядаємо нове число \(a\) тоді якщо \(dp[s] =\)true, тоді ми можемо сказати що тепер \(\text{dp}[s + a] =\) true і це треба зробити по усіх значеннях \(s\).
Ми будемо розглядати числа в порядку зростання. Перед тим як розглянути чергове число \(a_i\), перевіримо чи ми з менших чисел могли утворити суму рівну поточному числу (перевірити значення \(\text{dp}[a_i]\)). Якщо \(\text{dp}[a_i] =\) true, то це означає що порушується умова на супер послідовність.
Для розв’язання цієї задачі можна переформулювати задачу так: для кожного \(j\) треба порахувати мінімальну незбалансованість для \(j\) пар. Тоді щоб отримати відповідь на початкову задачу нам треба знайти найбільше \(j\), для якого незбалансованість не перевищує \(k\).
Посортуємо масив за зростанням. Оптимально парувати тільки ті елементи, які є сусідніми в посортованому масиві.
Нехай \(\text{dp}[i][j]\) — мінімальна незбалансованість, якщо ми розглянули перші \(i\) чисел та утворили з них \(j\) пар.
Маємо два переходи.
Спаруємо сусідні (у посортованому масиві) елементи \(a_{i-1}\) та \(a_i\). Оновимо \(\text{dp}[i][j]\) значенням \(\text{dp}[i - 2][j - 1] + (a_i - a_{i - 1})\).
Не паруємо \(a_i\) із жодним іншим елементом. У цьому разі оновимо \(\text{dp}[i][j]\) значенням \(\text{dp}[i - 1][j]\).
Позначимо \(f(m)\) відповідь на задачу залежно від кількості студентів \(m\). Ця функція є опуклою вгору, тобто виконується \(f(m + 2) - f(m + 1) \le f(m + 1) - f(m)\). Нам потрібно знайти відповідь для \(k\) студентів \(f(k)\).
Розглянемо функцію \(g(m) = f(m) - \lambda m\) для деякого параметра \(\lambda\). Функція \(g(m)\) також є опуклою вгору, як сума опуклої вгору та лінійної.
Термінами нашої задачі можна сказати, що \(g(m)\) — це максимальне задоволення студентів, щоб роздати пробірки \(m\) студентам, причому ми «платимо» (віднімаємо від задоволення) \(\lambda\) одиниць за кожного студента.
Тепер розглянемо дещо іншу задачу, ніж початкова. Потрібно роздати пробірки студентам, щоб максимізувати сумарне задоволення, коли за кожного студента «платимо» \(\lambda\) одиниць, причому дозволено роздати пробірки скільком завгодно студентам.
Цю задачу можна розв’язати таким динамічним програмуванням. Будемо підтримувати два значення в динаміці: \(\text{dp}[i].\text{first}\) — власне відповідь на задачу, коли розглянули перших \(i\) пробірок, і \(\text{dp}[i].\text{second}\) — оптимальна кількість студентів, яким потрібно роздати ці пробірки. Перехід динаміки: \(\text{dp}[i].\text{first} = \max_j \text{dp}[j].\text{first} + c[j + 1][i] - \lambda\), де \(c[j + 1][i]\) — кількість різних речовин на проміжку \([j + 1, i]\). У цій динаміці в першу чергу максимізовуємо значення \(\text{first}\), а в другу чергу максимізовуємо \(\text{second}\).
Тоді \(\text{dp}[n].\text{first}\) — відповідь, коли роздамо всі \(n\) пробірок. Тут не накладаються обмеження на кількість студентів, тому \(\text{dp}[n].\text{first} = \max_m g(m)\) — максимальному значенню функції \(g\) для всіх можливих кількостей студентів.
Позначимо \(m_\text{опт}\) оптимальну кількість студентів для деякого параметра \(\lambda\). Тобто \(\text{dp}[n].\text{first} = \max_m g(m) = g(m_\text{опт})\). Якщо \(m_\text{опт} = k\), тоді можна знайти значення \(f(k) = g(k) + \lambda k\) — це й буде відповіддю на задачу.
Як підібрати таке \(\lambda\), щоб для нього виконувалося \(m_\text{опт} = k\)? Зауважимо, що при \(\lambda = 0\) (нічого не «платимо» за кількість студентів), оптимально роздати пробірки \(n\) студентам, тобто \(m_\text{опт} = n\) для \(\lambda = 0\). А коли \(\lambda = n\) (дорого «платити» за студентів), то вигідно взяти лише одного студента, тобто \(m_\text{опт} = 1\) для \(\lambda = n\). Чим більше \(\lambda\), тим дорожче «платити» за студентів, тим буде меншою оптимальна кількість студентів \(m_\text{опт}\).
Для знаходження параметра \(\lambda\) скористаємось двійковим пошуком. Потрібно знайти таке найбільше \(\lambda\), що \(m_\text{опт} \ge k\), тобто \(\text{dp}[n].\text{second} \ge k\).
Відповіддю на задачу буде \(f(k) = g(m_\text{опт}) + \lambda k = \text{dp}[n].\text{first} + \lambda k\).
Складність розв’язку: \(O(n^2 \log n)\).
Нехай \(\text{dp}[i][0]\) — відповідь на задачу для перших \(i\) місяців, якщо Зеник після цих місяців перебуває на загальній системі, а \(\text{dp}[i][1]\) — якщо на спрощеній.
Переходи динаміки:
Зеник був на загальній, залишається на загальній: \(\text{dp}[i][0] \to \text{dp}[i + 1][0]\).
Зеник був на загальній, переходить на спрощену: \(\text{dp}[i][0] \to \text{dp}[i + 1][1]\).
Зеник був на спрощеній, залишається на спрощеній: \(\text{dp}[i][1] \to \text{dp}[i + 1][1]\).
Зеник був на спрощеній, переходить на загальну: \(\text{dp}[i][1] \to \text{dp}[k][0]\), де \(k = \min (i + m, n)\). Тут ми повинні забезпечити, що Зеник залишатиметься на загальній системі принаймні \(m\) місяців (або до кінця).
Щоб відновити відповідь, потрібно для кожного стану \(\text{dp}\) підтримувати, яким попереднім станом ми його оновили.
Складність розв’язку: \(O(n)\).
Це задача про рюкзак.
Нехай \(\text{dp}[i][j]\) — максимальний прибуток, який ми отримаємо, якщо ми розглянули \(i\) холодильників, та купили холодильників на суму \(j\) гривень.
Переходи динаміки:
Не купуємо \(i\)-ий холодильник: \(\text{dp}[i][j] \to \text{dp}[i + 1][j]\).
Купуємо \(i\)-ий холодильник за \(a_i\) гривень: \(\text{dp}[i][j] \to \text{dp}[i + 1][j + a_i]\).
Складність розв’язку: \(O(n \cdot \text{max\_sum}) = O(n \cdot n \cdot \text{max\_a}) = O(n^2 \cdot \text{max\_a})\).
Потрібно відсортувати чемодани за об’ємом. Після цього зробимо динаміку схожу на найдовшу зростаючу підпослідовність.
Послідовність довжини \(n \ge 2\), яка задовольняє вимоги, має вигляд \(xxxxxxx = 47xxxxx\) (якщо починається цифрою \(4\)) або \(xxxxxxx = 7xxxxxx\) (якщо починається цифрою \(7\)).
Кількість потрібних рядків рядків довжини \(n\) порахуємо динамікою \(\text{dp}[n] = \text{dp}[n - 2] + \text{dp}[n - 1]\). Значення динаміки — це послідовність чисел Фібоначчі, яка починається зі значень \(\text{dp}[0] = 1, \text{dp}[1] = 2\).
Якщо \(k > \text{dp}[n]\), то відповіді не існує.
Щоб знайти \(k\)-у послідовність, ставимо цифри по черзі зліва направо.
Нехай \(n \ge 2\). Тоді виконуємо такий процес.
Якщо \(k \le \text{dp}[n - 2]\), то послідовність \(xxxxxxx\) має вигляд \(47xxxxx\). Ставимо цифри \(47\) і зменшуємо \(n\) на \(2\).
Якщо \(k > \text{dp}[n - 2]\), то послідовність \(xxxxxxx\) має вигляд \(7xxxxxx\). Зменшуємо \(k\) на \(\text{dp}[n - 2]\), ставимо цифру \(7\) і зменшуємо \(n\) на \(1\).
Порахуємо розмір кожної з компонент зв’язності. Тепер для кожної кількості балів від 0 до \(n\) порахуємо чи можемо ми її набрати. Це можна зробити за допомогою динаміки про рюкзак. Для оптимізації використаємо бітсети.
Нехай \(\text{dp}[i][j][0/1]\) — кількість щаслиих чисел довжини \(i\), цифри змінюються \(j\) разів і визначена перша цифра (0 відповідає за 4, 1 відповідає за 7). Ми можемо легко перерахувати таку динаміку так:
\(\text{dp}[i + 1][j][0]\) += \(\text{dp}[i][j][0]\)
\(\text{dp}[i + 1][j + 1][0]\) += \(\text{dp}[i][j][1]\)
\(\text{dp}[i + 1][j + 1][1]\) += \(\text{dp}[i][j][0]\)
\(\text{dp}[i + 1][j][1]\) += \(\text{dp}[i][j][1]\)
Тепер переберемо довжину відповіді — \(len\). Якщо \(\sum_{j \in lucky} dp[len][j][0] + dp[len][j][1]\) < \(n\), то ця довжина є замалою. Коли ми переходимо до \(len + 1\), потрібно від \(n\) відняти кількість депутатських щасливих чисел довжини \(len\). Тепер коли в нас є фіксована довжина, потрібно знайти \(n\)-е депутатське щасливе число число довжини \(len\). Для цього будемо йти від старших цифр до молодших і пробувати жадібно ставити 4 або 7. Перевіряти чи можемо поставити ми будемо за допомогою порахованої перед тим динаміки.
Впорядкуємо відрізки за правим кінцем в порядку зростання. Якщо праві кінці збігаються, то за лівим у порядку спадання. Стиснемо координати і будемо розглядати тільки цікаві (ті які є кінцем хоча б одного відрізка).
Порахуємо динаміку \(\text{dp}[x]\) — відповідь на задачу, якщо останній відрізок, який ми взяли має лівий кінець в координаті \(x\). Коли ми розглядаємо \(i\)-тий відрізок, то ми вже розглянути всі, які закінчуються раніше. Нам підходять всі відрізки, у яких лівий кінець є лівіше ніж лівий кінець \(i\)-того відрізка. Оновимо \(\text{dp}[l[i]] = \max_{x < l[i]}{\text{dp}[x] + 1}\). Щоб шукати максимум використаємо дерево Фенвіка або дерево відрізків.
Розбір задачі доступний на сайті - Обласна iнтернет олiмпiада 2023 - Тур 2 (розбір).
Для розвязання цієї задачі можна використати різноманісті структури даних і підходи, наприклад, дерево відрізків, дерево Фенвіка, коренева декомпозиції та інші.
У даній задачі потрібно реалізувати двійкові підйоми і пошук нанижчого спільного предка.
Визначимо, що в день \(i\) буде в кожній вершині значення рівне \(x_v + i\), будемо підтримувати такий інваріант. Тоді для обрахунку кількості квітів на шляху нам достатньо порахувати суму значень \(x_v\) і додати кількість вершин на шляху помножена на номер дня \(i\). Запит першого типу змінює \(x_v\) на \(-i\) так аби підтримувати інваріант. Тому задача перетворюється до зміни значення в вершині і обрахунку суми на шляху.
Першочергово змінимо запити, збільшити значення вершин на шляху від \(a\) до \(b\) можна розкласти на збільшення значення на шляхах до кореня від вершин \(a\), \(b\) та їх \(lca\) і окремо треба збільшити значення в \(lca\).
Розглянемо запит суми в піддереві вершини \(x\), нам треба порахувати по усіх запитах \({v, val}\) з піддерева порахувати значення \((d[v] - d[x] + 1) * val = d[x] * (-val) + (d[v] + 1) * val\), де \(d[v]\) - глибина вершини. Ми можемо порахувати в піддереві суму \(-val\) - нехай це буде \(k\), також суму значень \((d[v] + 1) * val\) - її позначемо як \(b\). Для того аби порахувати відповідь нам треба порахувати формулу \(d[x] * k + b\).
Розбір задачі доступний на сайті - Розбір районної 2022.
F. Найпростіші запити на дереві
Переформулювавши задачу на масиві можемо отримати таку задачу: додати значення усім числам на відрізку і знайти максимум на відрізку. Для цього можна використати дерево відрізків з обіцянками або лінивим оновленням.
Перетворимо рядки до маленьких букв і можна вставити ці рядки в множину (set) і вивести розмір цієї множини як відповідь.
Розбір задачі доступний на сайті - Розбір районної 2021.
Розбір задачі доступний на сайті - Розбір обласної 2017.
В даній задачі потрібно перевірити чи жеребець і кобила знаходяться у
одній чверті. Для перевірки цього можна перевірити, чи знак координати
по осях x
та y
є однаковим. Найпростіше таку
перевірку можна зробити перевіривши чи добутки значень їх x
та y
координат є додатними числами.
Перш за все треба перевірити чи існує квадрат, що з площею рівною сумарній площі необхідній для коней. Нехай існує такий квадрат зі стороною \(n\), тоді у випадку якщо \(n\) парне, то ми завжди можемо розташувати наших коней.
У випадку коли \(n\) є непарним, то достатньо перевірити чи можна розташувати деяких коней, щоб покрити перший рядок і перший стовпець. Якщо вийде, то ми просто перейдемо до квадрата зі стороною \((n - 1)\), який є парним і ми в нього завжди зможемо розташувати коней. Оскільки ми можемо розташовувати лише лошат і кобил в перший рядок і стовпець, то нам цікаво чи в нас є достатньо цих коней, щоб покрити повністю ці ділянки: \(a + 2b \ge 2n - 1\).
Задачу можна переформулювати у таких термінах: ми залишаємо лише підрядок від \(l\)-го до \(r\)-го символу, за одну операцію можна видалити підрядок який має перший і останній символ однакові та має хоча б два символи та потрібно відповісти чи можна такими операціями видалити заданий підрядок.
У випадку коли \(l = r\) зрозуміло,
що ми не можемо виконати жодної операції тому відповідь No
.
Якщо ж \(s[l] = s[r]\) тоді ми за одну
операцію можемо видалити весь цей підрядок.
Для випадку коли \(s[l] \neq s[r]\) достатньо перевірити чи існує така позиція \(l < i < r - 1\) така що \(s[l] = s[i]\) та \(s[i + 1] = s[r]\) у такому випадку ми можемо видалити весь цей підрядок за дві операції, якщо ж такої позиції немає, то ми не зможемо видалити цей підрядок.
Дану задачу можна переформулювати в термінах графів: кожна хата це вершина графа, а також для зручності визначимо вершину яка буде початком для кур’єра, тоді для того аби дійти з цієї вершини до хати, в якій кур’єр купить овес необхідно заплатити ціну за мішок. Також ми знаємо скільки коштує переміститись між сусідніми хатами та ціна на переміщення між деякими парами хат — ціна проїзду в маршрутці.
Шукана відповідь буде рівна найдешевшому = найкоротшому шляху з початкової вершини для кур’єра до відповідної хати. Для пошуку найкоротшого шляху можна використати алгоритм Дейкстри.
Розглянемо певний шлях (\(a_1\), \(a_2\), \(\dots\), \(a_k\)) і нехай кількість сусідів для вершин на цьому шляху рівна \(sz_1\), \(sz_2\), \(\dots\), \(sz_k\) відповідно. Тоді такий шлях розділить дерево на \(1 + (\sum_{i = 1}^{k} sz_i) - 2(k - 1)\), так початково була одна компонента і кожне ребро з вершиною шляху збільшить кількість компонент на 1, окрім ребер ті що є на шляху - таких \(k - 1\) і ми їх врахували двічі. Цю формулу можна перетворити на таку \(3 + \sum_{i = 1}^{k} (sz_i - 2) = 3 + \sum_{i = 1}^{k} val_{a_i}\), де \(val_{v}\) рівне кількості сусідів вершини \(v\) мінус 2.
В термінах задачі нам потрібно максимізувати суму значень \(val_v\) на шляху починаючи з вершини \(w\) і додати 3 до цього значення. Знайдемо максимальний по сумі значень шлях у дереві \(A - B\), подібно до алгоритму пошуку діаметра в дереві. Можна довести що максимальний шлях з вершини \(w\) буде завершуватись у одній з вершин \(A\) або \(B\). Тому порахуємо сумарне значення на шляху з вершини \(A\) і вершини \(B\), відповідь буде максимальне значення з цих двох шляхів плюс 3.
Побудуємо граф із \(n\) вершин, де вершина відповідає за остачу по модулю \(n\). З вершини \(x\) будемо мати два переходи у вершини \((10x + 4)\%n\) та \((10x + 7)\%n\) - це буде означати що до побудованого числа з остачою \(x\) ми можемо доставити цифру в кінець і отримати числа з такими остачами. У такому графі нас цікавить в першу чергу найкоротший цикл з вершини що відповідає за остачу 0 і серед таких найкоротших циклів нас цікавить лексикографічно найменший. Для того аби отримати потрібний результат будемо виконувати пошук вшир, де першочергово будемо розглядати перехід з додаванням 4 і після цього з додаванням 7.
Розглянемо конструкцію де певне число \(val\) довжини \(len\) повторюємо певну кількість разів \(x\) так аби воно ділилось на \(n\). Розглянемо значення цього числа \(\frac{val \cdot (10^{len \cdot x} - 1)}{(10^{len} - 1)}\), це число має ділитись на \(n\), тобто \(val \cdot (10^{len \cdot x} - 1)\) має ділитись на \(n \cdot (10^{len} - 1) = m\).
Використаємо теорему Ейлера: для взаємнопростих \(a\) та \(m\) виконується \(a^{\varphi(m)} \equiv 1 \pmod m\). Розглянемо такі \(n\) які взаємнопрості з 10, також використовуючи те що \(10^{len} - 1\) взаємнопросте з 10, отримаємо \(10^{len \cdot \varphi(m)} - 1 \equiv 0 \pmod m\). Якщо ми число \(val\) повторимо \(x \cdot \varphi(n(10^{len}-1))\) разів то таке утворене число буде ділитись на \(n\), проте це правильно лише для \(n\) взаємнопростих з 10.
Розглянемо що відбувається коли \(n\) не є взаємнопростим із 10. Якщо \(n\) ділиться на 5 то у такому випадку не існує ніякого щасливого числа, яке ділиться на 5.
У іншому випадку \(n\) ділиться на 2, це означає що нам необхідно задовольнити аби щасливе число ділилось на певний степінь двійки. Для вирішення цього візьмемо \(val = 447444474444447744\) - щасливе число яке ділиться на \(2^{18}\), а отже ділиться і на усі можливі степені які може містити число \(n\).
Можна показати що \((10^{18} - 1) \cdot \varphi(10^{18} - 1) \cdot \varphi(n)\) ділиться на \(\phi(n(10^{18} - 1))\). Отже, нам достатньо рядок \(447444474444447744\) повторити \((10^{18} - 1) \cdot \varphi(10^{18} - 1) \cdot \prod \varphi(n_i)\). Використовуючи правила ми можемо множити кількість повторів без жодних проблем.
У цій задачі потрібно підтримувати скільки грошей було у Зеника після кожної операції та перевірити чи було це значення від’ємним хоча б 1 раз.
Якщо ми знаємо, скільки менших значень повинно бути зліва і скільки менших справа, то їх сума – кількість менших значень всього в масиві.
Відповідно, якщо \(l_i+r_i = l_j+r_j\), то відповідні значення теж мають бути однакові. А якщо \(l_i+r_i > l_j+r_j\), то значення на позиції \(i\) має бути більшим за значення на позиції \(j\).
Масив \(a_i=l_i+r_i\) задовольняє ці умови. Оскільки відповідь завжди існує, то можна вивести цей масив.
Розглянемо \(i\)-тий біт. Якщо всі числа, які ми візьмемо в набір матимуть цей біт включений, то неможливо буде вибрати три числа з ксором 0, оскільки в ксорі цей біт входитиме тричі. Проте, після того, як ми взяли всі числа з \(i\)-тим бітом ми можемо взяти до множини ще щось.
Нехай ми хочемо взяти числа в яких старший біт буде або \(i\)-тий або \(j\)-тий. Нехай \(i > j\). Тоді ми можемо набрати в множину всі числа з \(j\)-тим бітом і всі числа з \(i\)-тим бітом, в яких \(j\)-тий біт виключений. Можна показати, що це і буде оптимальний спосіб обрати числа. Можна показати, що в оптимальній відповіді \(j = i - 1\).
Відповідно переберемо \(i\). Візьмемо всі числа з проміжку \([2^{i - 1}, 2^i + 2^{i - 1})\), які належать нашій множині.
Складність розв’язку \(O(n)\).
Використаємо метод динамічного програмування. Для кожного орієнтованого ребра \((v, p)\), де \(p\) — батько вершини \(v\), порахуємо математичне очікування часу, необхідного для переходу з вершини \(v\) до вершини \(p\). Тоді відповідь на задачу для будь-якої вершини \(v\) - це сума на вертикальному шляху від \(v\) до 1.
\(dp[v, p]\) можна порахувати наступним чином. Нехай \(t_1, t_2, ..., t_k\) - сини вершини \(v\), посортовані за зростанням значення \(dp[t_i, v]\). Тоді \(dp[(v, p)] = 1 + 2^{-k} + \sum_{i=1}^k (1 +dp[t_i, v]) \cdot 2^{-i}\).
Відсортуємо всі \(3 \cdot n\) точок за зростанням їхніх координат \(x\). У випадку рівності координат \(x\), відсортуємо за зростанням координат \(y\). Таким чином, отримаємо впорядкований список точок: \(P_1, P_2, \ldots, P_{3n}\).
Розділимо відсортований список точок на \(n\) груп по три сусідні точки: \[\{P_1, P_2, P_3\}, \{P_4, P_5, P_6\}, \ldots, \{P_{3n-2}, P_{3n-1}, P_{3n}\}\]
Для кожної групи з трьох точок побудуємо трикутник. Таким чином, отримаємо \(n\) трикутників, що задовольняють умову.
F. Обміни з максимальною сумою
Нехай ми хочемо замінити \(i\) елементів з лівої частини на \(i\) елементів з правої. Відповідь на задачу тоді буде: сума в лівій частині - сума \(i\) елементів, які ми заміняємо в лівій частині + сума \(i\) елементів, які ми заміняємо в правій частині. Можна показати, що однією з оптимальних послідовностей операцій буде:
Посунути \(i\) елементів зліва, які ми збираємося міняти в найправіші \(i\) позицій лівої частини. Тобто, поставити їх на позиції \(n - i\), \(n - i + 1\), …, \(n - 1\).
Посунути \(i\) елементів справа, які ми збираємося міняти в найлівіші \(i\) позицій правої частини. Тобто, поставити їх на позиції \(n\), \(n + 1\), …, \(n + i - 1\).
Виконати \(i \cdot i\) операцій, щоб свапнути елементи.
Порахуємо динаміку \(dp1_{i, j}\) — мінімальна сума \(i\) елементів в лівій частині, якщо ми зробили \(j\) ходів, щоб виконати перший крок. Аналогічно порахуємо динаміку \(dp2_{i, j}\) — максимальна сума \(i\) елементів в правій частині, якщо ми зробили \(j\) ходів, щоб виконати другий крок. Третій крок зробити просто. Таку динаміку можна рахувати за \(О(n^4)\).
Об’єднати такі дві динаміки можна за \(O(n^5)\), але це повільно. Модифікуємо трохи другу динаміку наступним чином: \(dp_{i, j}\) — Нехай ми зробили перший крок і виконуємо другий. Нам треба ще \(i\) елементів досунути в правій частині та ми зробили вже сумарно \(j\) кроків. Ми будемо її перераховувати за допомогою \(dp1\). Таку динаміку можна рахувати за \(O(n^4)\) і вона зразу покриє перші два кроки. Оскільки нам треба зробити щонайбільше \(k\) кроків, то треба взяти ще максимум на префіксі.
Розглянемо мінімальну відповідь, якщо лівий нижній кут зсувається вгору та вправо. 3 інші випадки розв’язуються так само, за допомогою віддзеркалення точок.
Посортуємо всі точки по \(x\), а при рівності по \(y\). Йтимемо зліва направо, розглянемо точку \(p_i\), яка має максимальну \(y\) координату серед всіх точок на суфіксі. Знайдемо такий найправіший індекс \(j\), що \(p_j.x \le p_i.x\) і \(p_j.y \geq p_i.y\). Тоді якщо перемістити прямокутник так, що його лівий нижній кут був у точці \((p_j.x, p_i.y)\), то всі точки опиняться на межах або поза межами прямокутника. Назвемо таку точку \((p_j.x, p_i.y)\) цікавою.
Цікаві точки можна легко знаходити за допомогою стека, де завжди виконується, що остання точка є найправішою та нийнижчою серед усіх у стеці, а якщо ми намагаємося додати точку, яка суперечить цьому, видалятимемо зі стека останню точку, поки умова не виконуватиметься. Порахуємо відповідь для всіх цікавих точок та виберемо мінімальну.
У цій задачі потрібно було вивести \(a+c\), якщо \(a<b\). Якщо ж \(a \ge b\), то вивести \(a\).
У цій задачі потрібно було перевірити усі задані умови. Найпростіше це було зробити, якщо спочатку пройтись по топ \(m\) команд, підтримуючи, скільки команд з кожного університету уже розглянуто.
Після цього можна пройтись по всіх командах поза топ \(m\) та додати по 1 команді кожного регіону, який ще не було розглянуто.
Зробимо двійковий пошук по відповіді. Нехай наразі потрібно перевірити, чи відповідь є не більшою за \(x\).
Будемо рахувати для вершини \(v\), чи можливо орієнтувати піддерево вершини \(v\). Для кожного сина \(to\) важливо, чи ми орієнтуємо ребро від \(v\) до \(to\) чи навпаки.
Якщо ми орієнтуємо ребро від \(v\) до \(to\), то нам важливо піддерево \(to\) орієнтувати так, щоб для нього виконувалась умова, а також мінімізувати кількість монет досяжних з вершини \(to\). Назвемо таке значення \(down_{to}\).
Якщо ми орієнтуємо ребро від \(to\) до \(v\), то також потрібно, виконувалась умова, а також мінімізувати найбільшу кількість монет досяжних з певної вершини, з якої також досяжна вершина \(to\). Назвемо таке значення \(up_{to}\).
Нехай \(A\) – це множина синів вершини \(v\) таких, що ми орієнтуємо ребро від неї до \(v\), \(B\) - множина синів, де ми орієнтуємо ребро до сина.
Тоді нам потрібно розбити на множини так, щоб \(max_{to \in A} up_{to} + \sum_{to \in B} down_{to} + a_v \le x\).
Якщо посортувати всіх синів по значенню \(up\), то вигідно деякий префікс взяти в множину \(A\) і суфікс в множину \(B\). Так ми зможемо перевірити, чи все ще виконується умова. Залишилось перерахувати значення \(up_v\) та \(down_v\).
\(up_v\) - мінімальне можливе значення \(max_{to \in A} up_{to} + \sum_{to \in B} down_{to} + a_v\).
\(down_v\) - мінімальне можливе значення \(\sum_{to \in B} down_{to} + a_v\), серед таких, що задовольняють умову.
Тож обидва ці значення можна порахувати разом з перевіркою умови двійкового пошуку.
Складність розв’язку \(O(n \log^2 n)\).
Відсортуємо всі числа в порядку зростання. Спробуємо закладати
матрицю діагоналями, тобто розглядатимемо клітинки в порядку зростання
\(i + j\). Клітинки з однаковим
значенням \(i + j\) потрібно розглядати
або в порядку зростання \(i\), або в
порядку спадання. Переберемо два варіанти. Розставимо всі числа від
менших до більших в клітинки в такому порядку. Перевіримо чи все
виконується. Якщо хоча б для одного варіанту все виконалося, то виведемо
відповідь. Інакше, відповідь NO
.
Якщо перший гравець може піти в якомусь з напрямків і досягнути безпечної точки швидше за другого гравця, то він точно може перемогти.
Така умова не виконується лише, якщо обидва гравці початково знаходяться в одній чверті, на одній діагоналі, та другий гравець ближче до осей, ніж перший. Тобто, якщо \(x_1>0\) та \(y_1>0\), то повинно виконуватись \(x_2, y_2 > 0\), \(x_1-y_1=x_2-y_2\), \(x_1<x_2\) та \(y_1<y_2\).
В такому випадку можна показати, що переможе другий гравець. Якщо перший гравець ходить в бік від осей, то другий гравець повторює його хід. Якщо ж до осей, то другий гравець робить хід, щоб залишитись на тій же діагоналі, але ближче до першого гравця.
Зауважимо, що \(b_i \ge b_{i-1}\) та \(c_i \ge c_{i+1}\), оскільки при додаванні нових значень в множину їх mex не може зменшуватись.
Якщо \(b_i \ne b_{i-1}\), то повинно виконуватись \(a_i=b_{i-1}\), адже жодне число зліва від \(i\) не дорівнює \(b_{i-1}\), а разом з \(a_i\) уже хоча б одне число має бути рівним \(b_{i-1}\). Аналогічно, \(a_i=c_{i+1}\), якщо \(c_i \ne c_{i+1}\).
Таким чином, ми маємо вже деякі значення зафіксовані. Подивимось, що ще необхідно, щоб виконувалась умова. Якщо \(b_i \ne b_{i-1}\) також потрібно, щоб усі значення \(b_{i-1}+1, b_{i-1}+2, \dots, b_{i}-1\) були на префіксі \([1, i-1]\) хоча б раз. Додамо обмеження для таких значень \(v \in [b_{i-1}+1, b_i-1]\), що вони повинні бути хоча б раз на проміжку \([1, l_v]\), тут \(l_v=i-1\). Аналогічно зробимо обмеження, що значення \(v\) повинне бути хоча б раз на суфіксі \([r_v, n]\).
Викинемо ті обмеження, які вже виконані уже зафіксованими значеннями. Далі зауважимо, якщо для значень \(u < v\) існують обмеження на префікс, то \(l_u \le l_v\). Та якщо на суфікс, то \(r_u \ge r_v\). Цю властивість можна отримати напряму з того, як ми генеруємо обмеження та того, що масиви \(b\) та \(c\) неспадний і незростаючий відповідно.
Тобто, якщо \(u<v\), то і префікс і суфікс на який потрібно поставити \(v\) є більшим за відповідний префікс чи суфікс для \(u\). Це означає, що ми можемо жадібно ставити значення від найменших.
Будемо розглядати значення від 1 до \(n\). Якщо для цього значення немає обмежень, то можна його пропустити. Якщо для значення \(v\) існують обмеження \([1, l_v]\), \([r_v, n]\), \(r_l \le l_v\) та на проміжку \([r_v, l_v]\) ще є незаповнені значення, то поставимо туди значення \(v\). Інакше, якщо існує обмеження \([1, l_v]\), то поставимо значення \(v\) на найлівіше вільне місце, та на найправіше вільне місце, якщо існує обмеження \([r_v, n]\).
Для зберігання вільних позицій використаємо структуру даних set. Якщо в кінці залишились ще вільні позиції, то поставимо там будь-які великі значення.
Складність розв’язку \(O(n \log n)\).
Помітимо, що в повному графі, де є усі можливі ребра, умова про відповідність найкоротших шляхів у графі з евклідовою відстанню виконується. Проте ми можемо видалити ребро між вершинами \(i\) та \(j\), якщо існує вершина \(k\), яка лежить на відрізку між точками \(i\) та \(j\). Видалення таких ребер не змінить найкоротші шляхи у графі. Можна довести, що будь-які інші ребра видаляти не можна, оскільки в такому випадку найкоротший шлях між відповідними вершинами не буде рівним їхній евклідовій відстані.
Для того аби порахувати відповідь швидко, ми для кожної вершини дивимось скільки є унікальних напрямків до інших вершин. Напрямки можна зберігати як \((x, y)\), де \(x\) та \(y\) взаємнопрості, маючи такі пари нам треба порахувати швидко кількість унікальних.
Складність \(O(n^2 \cdot \log n)\).
Оскільки числа в масиві натуральні, то щоб \(b_i\) ділилось на \((b_{i + 1} + b_{i + 2})\), необхідно аби ця сума була меншою або рівною за \(b_i\). Формально має виконуватись нерівність \(b_i \ge (b_{i + 1} + b_{i + 2}) \ge (b_{i + 1} + 1)\), а отже \(b_i > b_{i + 1}\). Це означає, що якщо масив впорядкований не за спаданням, то умова на подільність не виконуються.
Далі, після впорядкування, необхідно перевірити умову подільності для
кожного індексу \(i\) від \(1\) до \(n -
2\). Якщо умова виконується для всіх індексів, відповідь —
Yes
, інакше — No
.
Складність \(O(n \cdot \log n)\).
Якщо ми зробимо перший запит на підвідрізку не зі всіх елементів, то цей запит не дасть нам достатньо інформації, оскільки ми дізнаємось лише позицію мінімуму на відрізку, але не можемо нічого сказати про значення цього мінімуму. Отже, перший запит доцільно робити на всьому масиві, щоб одразу визначити позицію числа 1.
Якщо ми знайдемо позицію числа 1, але це число не є крайнім елементом масиву, то ми не можемо отримати достатньо інформації для визначення розташувань решти чисел. Наприклад, у масивах 2, 3, 1, 4, 5 та 4, 5, 1, 2, 3 ми можемо дізнатися лише позицію числа 1, але не зможемо визначити позиції інших чисел.
Для того аби дізнатись позицію числа \(x > 1\), необхідно щоб число 1 було на крайній позиції (1 або \(n\)). Це дозволяє нам робити запити які не включають 1. У такий спосіб ми переходимо до меншої задачі — пошуку числа \(x\) у перестановці чисел від 2 до \(n\).
Складність \(O(n)\).
Якщо в масиві \(a\) усі сусідні елементи різні, то це масив вже задовольняє умови задачі. У інакшому випадку, якщо в масиві \(a\) є сусідні елементи, які рівні, то значення \(max_{1\le i \le n}(b_i - a_i)\) буде хоча б 1.
Будемо будувати масив \(b\) поступово:
\(b_1 = a_1\),
для наступних елементів, якщо \(a_i \ne b_{i-1}\), то ми можемо вибрати \(b_i = a_i\),
інакше оберемо \(b_i = a_i + 1\), щоб зробити сусідні елементи різними.
Таким чином ми можемо побудувати масив \(b\), який задовольняє всі умови задачі.
Складність \(O(n)\).
F. Minimize the Maximum Distance
Використаємо двійковий пошук, щоб знайти відповідь. Маючи обмеження на максимальну відстань \(d\), ми можемо що наша площина розіб’ється на такі прямокутники, в кожному з яких будь-які дві сусідні точки, по горизонталі або вертикалі, мають відстань не більшу за обмеження.
Розглянемо один прямокутник і визначимо чи можна його точки розбити на потрібні нам групи по 2 та по 3. У випадку коли в прямокутнику лише 1 точка, то ми взагалі не можемо ніяк розбити на групи. Якщо кількість точок в прямокутнику парна, то ми можемо розбити на групи по 2 і в ці групи будемо ставити пари сусідніх точок.
Останнім випадком є ситуація коли кількість точок є непарною, тоді можна довести що якщо існує розбиття на групи, то існує й розбиття на такі групи що є лише одна група із 3-х точок. Ці три точки або три підряд в одному ряді, або три підряд в одному стовпці, або усі ці 3 точки знаходяться в двох сусідніх рядках та двох сусідніх стовпцях (як у малюнку для другого прикладу сині точки).
Якщо розфарбувати такий прямокутник у шаховому порядку, припустимо що кількість чорних більша за кількість білих точок. Група з 3-х точок повинна містити дві точки чорного кольору. Єдиним випадком коли це справді важливо, коли в прямокутнику або один рядок, або один стовпець. У решті випадків якщо можна вибрати хоча б якусь групу з 3-х точок, що задовольняють умову на максимальну відстань, то й можна вибрати групу з 3-х точок, що буде задовольняти одразу умову на відстань та умову на те що дві точки чорного кольору.
Враховуючи вищесказане, нам цікаво лише прямокутники із непарною кількістю елементів. Якщо у нас утвориться прямокутник \(1 \times 1\), то ми знаємо що така відстань є поганою. Після цього нам цікаво чи немає жодних проблем у прямокутниках \(1 \times k\) або \(k \times 1\). Наступним кроком ми можемо видалити ті прямокутники в яких можна вибрати групу з 3-х горизонтально або вертикально послідовних точок.
Серед тих що залишились потрібно перевірити чи є в кожному прямокутнику \(r_i\) та \(c_j\) такі що \(\sqrt{r_i^2 + c_j^2} \le d\). Оскільки прямокутників може бути багато, знайдемо окремо \(\max \min r_i\) по рядках та \(\max \min c_j\) по стовпцях. Тоді достатньо перевірити чи \(\sqrt{(\max \min r_i)^2+(\max \min c_j)^2} \le d\)
Складність \(O((n + m) \cdot \log)\).
G. Maximize the Minimum Distance
Будемо розглядати точки в задачі як клітинки прямокутника зі сторонами \(n\) та \(m\), а координати це індекси клітинки в такій матриці.
Розглянемо конструкцію у випадку коли \(n\) та \(m\) одночасно парні. У такій ситуації ми можемо розрізати прямокутник на 4 менші однакові прямокутники, розрізами посередині рядків та стовпців. Тепер ми можемо співставити лівий верхній прямокутник із нижнім правим, та два інші. Тобто будемо робити по 2 клітинки кожного кольору. Детальніше співставлення можна подивитись на рисунку 1 нижче.
Якщо ж одне з чисел \(n\) та \(m\) є парним, а інше непарне, то розрізати на прямокутники треба дещо інакше. Наприклад, коли кількість рядків непарна, то ми можемо ліву частину центрального рядка долучити до лівого верхнього прямокутника і праву частину до правого нижнього прямокутника. Детальніше співставлення можна подивитись на рисунку 2 нижче.
У випадку коли обидва числа непарні, то ми зробимо подібний процес зі стовпцем. Проте станеться така ситуація, що центральну клітинку покривають і лівий верхній, і нижній правий прямокутники. То пофарбуємо ліву верхню клітинку, праву нижню клітинку і центральну в один колір. Детальніше співставлення можна подивитись на рисунку 3 нижче.
В усіх випадках така конструкція дає найкращу можливу відповідь, оскільки для кожної з центральних клітинок неможливо отримати відстань кращу за \(\lfloor \frac{n}{2} \rfloor ^2 + \lfloor \frac{m}{2} \rfloor ^2\).
Складність \(O(n \cdot m)\).
З’єднувати можливо тільки вершини однакового кольору, інакше неможливо зробити першу операцію.
Розглянемо таку інтерпретацію процесу з умови: назвемо спершу великою вершиною – вершину, яка з’єднує обидва дерева. Далі за кожну операцію будемо об’єднувати велику вершину з певною вершиною \(u\), якщо в обох деревах існує ребро між великою вершиною і вершиною \(u\). Усі ребра, які виходили зі старих вершин, тепер будуть виходити з нової великої вершини.
Зробимо схожий процес: поки у двох деревах є однакове ребро, об’єднаємо в обох деревах ці вершини в одну вершину. Якщо такий процес не об’єднав усі вершини в кожному з дерев в одну, то відповідь 0, адже в одну велику вершину теж не вийде об’єднати. Такий процес не залежить від початкової великої вершини, тож його можна зробити один раз.
Щоб реалізувати цей процес будемо підтримувати усі інцидентні ребра для вершини в списку та з’єднувати ребра від вершини з меншим степенем до вершини з більшим степенем. Складність такого алгоритму буде \(O(n \log^2 n)\), оскільки нам ще також потрібно використати set чи схожу структуру даних, щоб підтримувати, які ребра збігаються в обох деревах.
Подивимось, коли ми об’єднували вершини \(u\) та \(v\), які ребра відповідають цьому об’єднанню в оригінальних деревах. Нехай це \((u_1, v_1)\) в першому дереві та \((u_2, v_2)\) в другому. Якщо \(u_1 \ne u_2\), то якщо велика вершина спершу об’єднала вершини \(v_1\) чи \(v_2\), то ми не зможемо об’єднати також \(u_1\) і \(u_2\). Аналогічно, якщо \(v_1 \ne v_2\). Тож якщо \(u_1 = u_2\), додамо в додатковий граф напрямлені ребра \(v_1 \to u_1\), \(v_2 \to u_1\). Це означає, що якщо ми об’єднали в велику вершину вершини з \(v\), то зможемо об’єднати також вершини з \(u\). Аналогічно додамо напрямлені ребра, якщо \(v_1=v_2\). Тоді відповідь – це кількість вершин, з яких досяжні всі інші вершини в додатковому графі. Таке значення можна знайти, якщо зробити топологічне сортування, або також існують простіші методи, які враховують специфічну структуру додаткового графа.
Для чисел \(k > \frac{n}{2}\) є лише одне можливе значення для \(a_i\), яке є множником \(k\), це число \(k\). Це означає, що в масиві повинні бути всі числа від \(\lfloor \frac{n}{2} \rfloor + 1\) до \(n\). Таким чином масив матиме щонайменше \(\lceil \frac{n}{2} \rceil\) елементів.
Для кожного числа \(k \le \frac{n}{2}\) можна знайти число в інтервалі \([\lfloor \frac{n}{2} \rfloor + 1, n]\), яке ділиться на \(k\). Це випливає з того що розмір проміжку більший або рівний за \(k\). Враховуючи вищесказане, масив з елементів від \(\lfloor \frac{n}{2} \rfloor + 1\) до \(n\) є мінімальним можливим масивом, що задовольняє усі умови задачі.
Складність \(O(n)\).
Без обмеження загальності вважатимемо, що \(n <= m\). Впорядкуємо масив \(a\) у порядку зростання, а масив \(b\) у порядку спадання. Оскільки ми хочемо максимізувати відстань, то з масиву \(b\) вигідно брати лише елементи на префіксі та суфіксі. Переберемо \(len\) —кількість елементів з префіксу \(b\) ми беремо, та паруємо їх з суфіксом масиву \(a\). Відповідно префікс масиву \(a\) довжини \(n - len\) паруємо з суфіксом масиву \(b\). Тоді відповідь буде рівною \[\max_{len \in [0, n]} (\sum_{i=n-len}^{n - 1} a_i - \sum_{i=0}^{len} b_i) + (\sum_{i=m-len}^{n - 1} b_i - \sum_{i=0}^{len} a_i)\].
Таку формулу можна рахувати за допомогою часткових сум, або перераховувати доданки в процесі зміни \(len\).
Складність \(O(n)\).
Будемо рахувати відповідь в процесі обходу дерева в глибину. При вході у вершину потрібно додати її значення до множини, а при виході видалити. Тепер після входу потрібно знайти відповідь. Подивимося як зміниться відповідь, якщо ми перейшли від батька до сина. Нехай ми прийшли до вершини \(v\). Відповідь може або не змінитися, або збільшитися, якщо найдовший відрізок буде містити значення \(a_v\).
Для того аби знайти найдовший відрізок зі значенням \(a_v\), і оновити ним відповідь, можна використати сет. У цьому сеті ми можемо зберігати відрізки \([l, r]\), такі що на шляху від кореня до цієї вершини були усі значення від \(l\) до \(r\) включно. Тепер при вході у вершину \(v\) цей сет може змінитись в один із чотирьох способів:
Ніяк не зміниться, якщо число \(a_v\) уже зустрічалось на шляху до кореня.
Утвориться новий відрізок довжини 1 — \([a_v, a_v]\).
Довжина якогось відрізка збільшиться на 1. Такий відрізок мав мати або \(r = a_v - 1\), або \(l = a_v + 1\).
Два відрізки об’єднаються в один, відрізки \([l, a_v - 1]\) та \([a_v + 1, r]\) об’єднаються в один \([l, r]\).
Коли ми будемо виходити з вершини \(v\), нам треба скасувати усі зміни які ми робили в цій вершині. Ми можемо запам’ятати які відрізки ми видалили з сету при вході і які додали. При виході видалимо ті що додали і додамо ті що видалили.
Складність \(O(n \cdot \log n)\).
Використовуючи замощування на рисунку 4 ми можемо досягти \(2 \cdot n \, \% \, 3\) вільних клітинок.
Складність \(O(1)\).
У даній задачі необхідно було написати декілька перевірок для
визначення властивостей заданого символу. Для перевірки, чи символ є
літерою англійського алфавіту, можна скористатися вбудованими функціями
або методами. Наприклад, у C++ це функція isalpha
, а в
Python — метод isalpha
. Для розрізнення великих і малих
літер можна використати isupper
та islower
у
C++ або відповідні методи в Python. Також можна виконати перевірку на
належність символа до діапазонів, наприклад,
if (’a’ <= ch and ch <= ’z’)
для малих літер та
if (’A’ <= ch and ch <= ’Z’)
для великих.
Для визначення порядкового номера символу в алфавіті зручно
скористатися властивостями того, як символи кодуються в комп’ютері.
Кожен символ має свій спеціальний код — ASCII-код. Наприклад, велика
літера A
має ASCII-код \(65\), літера B
— код \(66\), ..., літера Z
— код
\(90\). Малі літери теж мають свої
коди: a
— \(97\),
b
— \(98\), ...,
z
— \(122\). Не потрібно
знати напам’ять коди для всіх букв — достатньо лише знати, що великі
букви в алфавітному порядку від A
до Z
мають
послідовні коди. Те саме виконується й для малих букв — малі букви в
алфавітному порядку від a
до z
також мають
послідовні коди.
ASCII-коди дозволяють легко обчислити порядковий номер будь-якої
літери в алфавіті. Для знаходження номера великої букви треба відняти
код літери A
від її коду й додати одиницю. Для малої ж
букви від її коду треба відняти код літери a
й додати
одиницю.
У C++ для великої букви це можна зробити так:
c - ’A’ + 1
, а для малої ось так:
c - ’a’ + 1
.
У Python ord(c) - ord(’A’) + 1
або
ord(c) - ord(’a’) + 1
.
Якщо символ не є літерою, необхідно перевірити, чи це цифра. Для
цього можна скористатися функцією isdigit
у C++ або методом
isdigit
у Python. Альтернативно, можна перевірити, чи
символ є в діапазоні ’0’
до ’9’
,
використовуючи умову
if (’0’ <= ch and ch <= ’9’)
.
Якщо символ не є ні літерою, ні цифрою, то він належить до категорії
спеціальних символів. У такому випадку виводимо
weird symbol
.
У цій задачі, подібно до задачі «Символ», необхідно вміти перевіряти, чи символ є великою літерою. Завдяки цьому ми можемо знайти індекс \(p\), з якого починається ім’я учня. Для кожного запису журналу перша велика літера після першої (тобто друга велика літера у рядку) буде початком імені.
Маючи індекс \(p\), ми можемо побудувати новий формат для кожного учня. Спочатку виводимо всі символи з позиції \(p\) до кінця рядка, а потім додаємо всі символи від початку до \(p\) (не включаючи саму позицію \(p\)). Це забезпечить перестановку прізвища та імені у вказаному форматі.
Спробуємо спростити задану формулу. Звернемо увагу, що у виразі \(\sum_{i=l}^{r} \sum_{j=l}^{r} (-1)^{i + j} \cdot (a[i] + a[j])\) є два доданки: \((-1)^{i + j} \cdot a[i]\) та \((-1)^{i + j} \cdot a[j]\). Ці доданки симетричні з точністю до перестановки індексів \(i\) та \(j\), тому достатньо порахувати лише один з них і результат помножити на \(2\).
Зафіксуємо \(i\) і розглянемо, яке значення дає внутрішня сума по \(j\): \[\sum_{j = l}^{r} (-1)^j \cdot (-1)^i \cdot a[i] = (-1)^i \cdot a[i] \cdot \sum_{j = l}^{r} (-1)^j.\]
Нехай \(c_{l, r} = \sum_{j = l}^{r} (-1)^j\). Значення \(c_{l, r}\) залежить тільки від парності \(l\) та \(r\).
\(c_{l, r} = 0\), якщо \(l\) і \(r\) мають різну парність.
\(c_{l, r} = 1\), якщо \(l\) і \(r\) обидва парні.
\(c_{l, r} = -1\), якщо \(l\) і \(r\) обидва непарні.
Загальну формулу тепер можна записати у вигляді:
\[f(n, a, l, r) = 2 \cdot c_{l, r} \cdot \sum_{i = l}^{r} (-1)^i \cdot a[i]\]
Залишилося навчитися ефективно обчислювати суму \(\sum_{i = l}^{r} (-1)^i \cdot a[i]\). Це можна зробити за допомогою префіксних сум. \(pref_k = \sum_{i = 1}^{k} (-1)^i \cdot a[i].\)
Таким чином, обробка одного запиту відбувається за \(O(1)\) після попередньої обробки масиву за \(O(n)\). Загальний час роботи алгоритму складає \(O(n + q)\).
Розглянемо розв’язок для блоку \(l_i \le
r_i \le 10^6\). Ми будемо зберігати всі елементи, які ще не
додані до множини, у спеціальній структурі, наприклад,
std::set
у C++.
Для кожного запиту \([l_i, r_i]\) з умови задачі ми:
Знаходимо перше число в
set
, яке більше або рівне за \(l_i\).Якщо це число \(\leq r_i\), ми видаляємо його.
Повторюємо процес, поки всі відповідні числа не будуть вилучені.
Оскільки в нас початково було \(10^6\) чисел і ми лише видаляємо числа з множини, то ми й не можемо видалити більше елементів, ніж було початково. Таким чином, кількість операцій видалення обмежена кількістю чисел, а кожна операція пошуку або видалення виконується за \(O(\log maxR)\), де \(maxR\) — максимальне значення \(r_i\).
Загальна складність цього підходу буде \(O((q + maxR) \cdot \log maxR)\), де \(q\) — кількість запитів.
Код розв’язку мовою C++ для цього блоку
Щоб розв’язати задачу на повний бал, додамо до set
не
всі можливі числа, а тільки цікаві. Цікавими є числа \(l_i\) та \(r_i+1\).
Тепер маючи всі цікаві числа, посортуємо їх. Їх можна розглядати, як координати на числовій прямій.
Далі зробимо той самий процес, що для меншого блоку, тільки тепер будемо за один раз видаляти не одне число, а цілий проміжок.