Автор задачі: | Мар'ян Шийка |
Підготував: | Мар'ян Шийка |
Розбір: | Мар'ян Шийка |
Основна ідея
Розглянемо два сусідні входження однакового значення на позиціях та , тобто
Спочатку кожен елемент зі значенням можна вважати таким, що потребує окремої операції. Проте іноді два сусідні входження можна занулити в межах однієї й тієї самої послідовності операцій, тобто друге входження не збільшує відповідь.
Це можливо тоді і тільки тоді, коли для всіх позицій , таких що i<k<j, виконуються дві умови:
a_k>x;
a_k\le R.
Перша умова означає, що між двома однаковими значеннями немає елемента, який стане нулем раніше або одночасно з ними та не дозволить об'єднати ці два входження.
Друга умова означає, що всі елементи між ними взагалі дозволено змінювати в поточному запиті. Оскільки x\in[L,R] та всі проміжні значення строго більші за , нижня межа для них виконується автоматично. Тому достатньо перевіряти лише верхню межу .
Позначимо через cnt_x кількість елементів масиву, рівних . Початково встановимо
Значення res_x означатиме кількість операцій, яку додають до відповіді елементи зі значенням .
Кожного разу, коли два сусідні входження можна об'єднати, значення res_x зменшується на .
Перша умова
Будемо проходити масив зліва направо та підтримувати pos_x — останню позицію, на якій зустрічалося значення .
Нехай поточна позиція дорівнює , a_j=x, а попереднє входження знаходиться на позиції
Потрібно перевірити, що
Мінімум на проміжку можна знаходити за допомогою дерева відрізків.
Важливо, що потрібно брати саме проміжок
не включаючи самі позиції та , оскільки на них значення дорівнює .
Якщо i+1>j-1, тобто два однакові елементи стоять поруч, ця умова виконується автоматично.
Якщо попереднього входження не існує, то об'єднувати поточний елемент немає з чим.
Друга умова
Для кожної пари сусідніх входжень , яка пройшла першу перевірку, знайдемо
Така пара може бути об'єднана в запиті тоді і тільки тоді, коли
Отже, кожній допустимій парі поставимо у відповідність подію
Подія означає, що починаючи з усіх запитів з R\ge mx можна зменшити
на одиницю.
Відсортуємо всі події за , а всі запити — за правою межею .
Будемо обробляти запити у порядку зростання . Перед відповіддю на черговий запит активуємо всі події, для яких
При активації події виконуємо
Відповідь на запит
Для запиту нас цікавлять лише початкові значення, що належать цьому проміжку.
Тому відповідь дорівнює
Для підтримки масиву використаємо дерево Фенвіка або дерево відрізків.
Спочатку в позицію записуємо cnt_x. При активації події робимо точкове оновлення на , а для кожного запиту знаходимо суму на проміжку .
Таким чином, усі запити можна обробити офлайн.
Загальна асимптотика — O((n+q)\log n).
Використання пам'яті — O(n+q).