Автор задачі: | Мар'ян Шийка Підготував: | Мар'ян Шийка Розбір: | Мар'ян Шийка |
Ідея
Кінцевий рахунок людини дорівнює максимальному значенню a_j серед усіх позицій, які вона відвідає за кроків.
Спочатку перевіримо, чи відповідь взагалі може існувати. Якщо для хоча б однієї людини, яка починає на позиції , виконується
то вже на першому кроці її рахунок стане більшим за потрібне значення . У такому випадку відповідь дорівнює .
Тепер згрупуємо людей за їхнім значенням . Для кожної такої групи поділимо людей на два типи:
Good — люди, для яких a_s=c. Така позиція вже сама забезпечує потрібний максимум.
Bad — люди, для яких a_s<c. Щоб їхній кінцевий рахунок став рівним , вони повинні відвідати позицію зі значенням a_i=c.
Розглянемо одну групу з однаковим . Кожну позицію з Good використаємо як анкор окремого циклу. До цього циклу можна додати не більше ніж x-1 позицій з Bad.
Таким чином, довжина кожного такого циклу не перевищує , тому кожна людина в ньому за кроків обов'язково відвідає анкор зі значенням . При цьому всі інші позиції людей у цьому циклі мають значення не більше за , тому кінцевий максимум буде рівно .
Якщо після використання всіх позицій з Good ще залишилися елементи Bad, потрібно створити для них додаткові цикли. Як анкор для такого циклу використаємо вільну позицію без людини, для якої
До кожного такого анкора знову додаємо не більше ніж x-1 позицій з Bad.
Якщо потрібних вільних позицій зі значенням не вистачає, побудувати перестановку неможливо, тому виводимо .
Також, якщо x=1 і існує хоча б одна позиція з Bad, відповідь одразу дорівнює , оскільки така людина не встигне перейти на іншу позицію.
Після побудови всіх груп кожен створений набір позицій
замикаємо в цикл:
Усі позиції, які не були використані в жодному циклі, робимо нерухомими:
Таким чином отримуємо коректну перестановку, для якої кінцевий рахунок кожної людини дорівнює заданому значенню .
Загальна асимптотика — O(n\log n) через використання std::map.
Використання пам'яті — .