Запити по значеннях#12784

Запити по значеннях (Розбір)

Автор задачі:

Мар'ян Шийка

Підготував:

Мар'ян Шийка

Розбір:

Мар'ян Шийка

Основна ідея

Розглянемо два сусідні входження однакового значення на позиціях та , тобто

a_i=a_j=x.

Спочатку кожен елемент зі значенням можна вважати таким, що потребує окремої операції. Проте іноді два сусідні входження можна занулити в межах однієї й тієї самої послідовності операцій, тобто друге входження не збільшує відповідь.

Це можливо тоді і тільки тоді, коли для всіх позицій , таких що i<k<j, виконуються дві умови:

  1. a_k>x;

  2. a_k\le R.

Перша умова означає, що між двома однаковими значеннями немає елемента, який стане нулем раніше або одночасно з ними та не дозволить об'єднати ці два входження.

Друга умова означає, що всі елементи між ними взагалі дозволено змінювати в поточному запиті. Оскільки x\in[L,R] та всі проміжні значення строго більші за , нижня межа для них виконується автоматично. Тому достатньо перевіряти лише верхню межу .

Позначимо через cnt_x кількість елементів масиву, рівних . Початково встановимо

res_x=cnt_x.

Значення res_x означатиме кількість операцій, яку додають до відповіді елементи зі значенням .

Кожного разу, коли два сусідні входження можна об'єднати, значення res_x зменшується на .

Перша умова

Будемо проходити масив зліва направо та підтримувати pos_x — останню позицію, на якій зустрічалося значення .

Нехай поточна позиція дорівнює , a_j=x, а попереднє входження знаходиться на позиції

i=pos_x.

Потрібно перевірити, що

\min_{i<k<j} a_k>x.

Мінімум на проміжку можна знаходити за допомогою дерева відрізків.

Важливо, що потрібно брати саме проміжок

[i+1,j-1],

не включаючи самі позиції та , оскільки на них значення дорівнює .

Якщо i+1>j-1, тобто два однакові елементи стоять поруч, ця умова виконується автоматично.

Якщо попереднього входження не існує, то об'єднувати поточний елемент немає з чим.

Друга умова

Для кожної пари сусідніх входжень , яка пройшла першу перевірку, знайдемо

mx=\max_{i\le k\le j} a_k.

Така пара може бути об'єднана в запиті тоді і тільки тоді, коли

mx\le R.

Отже, кожній допустимій парі поставимо у відповідність подію

(mx,x).

Подія означає, що починаючи з усіх запитів з R\ge mx можна зменшити

res_x

на одиницю.

Відсортуємо всі події за , а всі запити — за правою межею .

Будемо обробляти запити у порядку зростання . Перед відповіддю на черговий запит активуємо всі події, для яких

mx\le R.

При активації події виконуємо

res_x\gets res_x-1.

Відповідь на запит

Для запиту нас цікавлять лише початкові значення, що належать цьому проміжку.

Тому відповідь дорівнює

res_L+res_{L+1}+\ldots+res_R.

Для підтримки масиву використаємо дерево Фенвіка або дерево відрізків.

Спочатку в позицію записуємо cnt_x. При активації події робимо точкове оновлення на , а для кожного запиту знаходимо суму на проміжку .

Таким чином, усі запити можна обробити офлайн.

Загальна асимптотика — O((n+q)\log n).

Використання пам'яті — O(n+q).