Відновити цикли#12783

Відновити цикли (Розбір)

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

Мар'ян Шийка

Підготував:

Мар'ян Шийка

Розбір:

Мар'ян Шийка

Ідея

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

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

a_s>c,

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

Тепер згрупуємо людей за їхнім значенням . Для кожної такої групи поділимо людей на два типи:

  • Good — люди, для яких a_s=c. Така позиція вже сама забезпечує потрібний максимум.

  • Bad — люди, для яких a_s<c. Щоб їхній кінцевий рахунок став рівним , вони повинні відвідати позицію зі значенням a_i=c.

Розглянемо одну групу з однаковим . Кожну позицію з Good використаємо як анкор окремого циклу. До цього циклу можна додати не більше ніж x-1 позицій з Bad.

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

Якщо після використання всіх позицій з Good ще залишилися елементи Bad, потрібно створити для них додаткові цикли. Як анкор для такого циклу використаємо вільну позицію без людини, для якої

a_i=c.

До кожного такого анкора знову додаємо не більше ніж x-1 позицій з Bad.

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

Також, якщо x=1 і існує хоча б одна позиція з Bad, відповідь одразу дорівнює , оскільки така людина не встигне перейти на іншу позицію.

Після побудови всіх груп кожен створений набір позицій

v_1,v_2,\ldots,v_t

замикаємо в цикл:

p_{v_1}=v_2,\quad p_{v_2}=v_3,\quad \ldots,\quad p_{v_t}=v_1.

Усі позиції, які не були використані в жодному циклі, робимо нерухомими:

p_i=i.

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

Загальна асимптотика — O(n\log n) через використання std::map.

Використання пам'яті — .