Префіксні MEX#12785

Префіксні MEX (Розбір)

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

Мар'ян Шийка

Підготував:

Мар'ян Шийка

Розбір:

Мар'ян Шийка

Ідея

Нехай

b=[a_L,a_{L+1},\ldots,a_R].

Для зручності переведемо межі запиту [l,r] у координати початкового масиву:

X=L+l-1,\qquad Y=L+r-1.

Розглянемо окремо випадки k=1, k=2 та k\ge 3.

k=1

Для поточного значення підтримуватимемо масив

c_i=f([a_L,a_{L+1},\ldots,a_i]).

Для L=1 цей масив можна побудувати звичайним проходом зліва направо, підтримуючи поточний MEX.

Розглянемо перехід від до L+1. Нехай

v=a_L.

Позначимо через наступну після позицію, на якій зустрічається значення . Якщо такої позиції немає, покладемо p=n+1.

Після видалення a_L значення prefix MEX можуть змінитися лише до наступного входження , тобто на позиціях до p-1.

Нехай — перша позиція, для якої

c_x>v.

Тоді після переходу до L+1 на всьому відрізку

[x,p-1]

новий prefix MEX дорівнюватиме . Отже, потрібно виконати операцію

c_i=v

для всіх i\in[x,p-1].

Для підтримки масиву використаємо дерево відрізків, яке вміє:

  • присвоювати одне значення всім елементам на відрізку;

  • знаходити суму на відрізку;

  • знаходити першу позицію , для якої c_x>v.

Тоді відповідь на запит з k=1 дорівнює

\sum_{i=X}^{Y}c_i.

k=2

Нехай

d=f(c).

Оскільки масив є неспадним, значення збільшується на одиницю щоразу, коли в вперше з'являється наступне необхідне значення

0,1,2,\ldots

Позначимо через p_x першу позицію, на якій у з'являється значення .

Число впливає на відповідь лише тоді, коли перші входження утворюють ланцюжок

p_0<p_1<\ldots<p_x.

У такому випадку поява збільшує prefix MEX на всіх позиціях починаючи з p_x. Тобто вона відповідає операції

d_i\gets d_i+1

для всіх

i\in[p_x,n].

Тому масив можна підтримувати другим деревом відрізків, яке підтримує додавання на відрізку та знаходження суми на відрізку.

При переході від до L+1 змінюється структура перших входжень, а разом з нею може змінитися початковий строго зростаючий ланцюжок

p_0<p_1<p_2<\ldots

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

[p_x,n]\gets +1.

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

[p_x,n]\gets -1.

Ці зміни можна підтримувати амортизовано, тому сумарна кількість оновлень протягом усього проходу за є лінійною.

Тоді відповідь на запит з k=2 дорівнює

\sum_{i=X}^{Y}d_i.

k\ge 3

Після третього застосування операції масив гарантовано стає константним.

Якщо a_L=0, то перший елемент дорівнює , тому в взагалі немає нуля. Отже,

f^2(b)=[0,0,\ldots,0],

а

f^3(b)=[1,1,\ldots,1].

Якщо a_L\ne0, то перший елемент дорівнює . Після ще одного застосування усі елементи отриманого масиву додатні, тому

f^3(b)=[0,0,\ldots,0].

Далі кожне застосування просто змінює константний масив з нулів на константний масив з одиниць і навпаки.

Таким чином, для k\ge3

g(k,b)=[1,1,\ldots,1]

тоді і тільки тоді, коли

(a_L=0)\mathbin{\mathrm{XOR}}(k\bmod 2=0).

В іншому випадку

g(k,b)=[0,0,\ldots,0].

Отже, відповідь на запит з k\ge3 дорівнює або

r-l+1,

або .

Складність

Обробляємо значення послідовно від до .

Для k=1 кожен перехід виконується за O(\log n).

Для k=2 кожне оновлення дерева відрізків займає O(\log n), а сумарна кількість необхідних змін є амортизовано лінійною.

Кожен запит з k=1 або k=2 обробляється за O(\log n), а запит з k\ge3 — за .

Отже, загальна асимптотика — O((n+q)\log n).

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