Премештања
Аутор: Никола Милосављевић
Текст и тест примери: Никола Милосављевић
Анализа решења: Никола Милосављевић
Тестер: Алекса Милојевић
Анализа
Означимо са R_i редни број ученика који седи за рачунаром i. На почетку је R_i = i за свако i = 1, 2, \ldots, N. У сваком премештању ми практично мењамо места два елемента низа R и након сваког премештања желимо да проверимо да ли постоји неки индекс i за који важи |i - R_i| > K.
Поменуту проверу можемо урадити праволинијски: у сваком од M корака заменимо два елемента низа а затим прођемо кроз цео низ и упоредимо |i - R_i| и K. Сложеност овог алгоритма је O(NM) и решава подзадатак 1 (20-30 поена) али је превише спор за остале подзадатке.
Приметимо да када вршимо проверу након i премештања, за све индексе j који нису учествовали у првих i премештања важи R_j = j; дакле, не морамо проверавати цео низ већ (у i-том кораку) само индексе из првих i премештања (А_1, B_1, A_2, B_2, \ldots, A_i, B_i; међу њима може бити истих). Ово даје алгоритам сложености О(M^2) што је довољно за прва два подзадатка (40-50 поена).
У трећем подзадатку важи K = N - 3. Међутим, једини индекси i за које је могуће да важи |i - R_i| < N - 3 су 1, 2, N-1 и N (остали се не могу довољно “удаљити”; проверити!) па је након сваке замене довољно проверити вредности R_1, R_2, R_{N-1} и R_N што нам даје укупну сложеност O(N+M) и решава овај подзадатак (20 поена).
Да бисмо решили цео задатак, приметимо да није неопходно стално проверавати пуно индекса већ је довољно да у сваком тренутку памтимо колико има индекса i за које важи |i - R_i| > K; означимо ту количину са x (на почетку је x = 0). Поменути индекс постоји акко је x > 0. Заменом два елемента низа вредност x се може променити највише за 2 и разликовањем неколико случајева лако “update”-ујемо x (нпр. ако је |A_i - R_{A_i}| \leq K и |B_i - R_{B_i}| > K, а |A_i - R_{B_i}| > K и |B_i - R_{A_i}| > K, тада се након i-тог премештања x повећава за 1, итд.) . Сложеност овог решења је O(N+M) и осваја свих 100 поена.