Розбір
Автор задачі: | Костянтин Денисов |
Задачу пiдготував: | Костянтин Денисов, Максим Шведченко |
Розбiр написав: | Костянтин Денисов |
Група 1. Переберемо всі можливі множини та перевіримо чи можемо відсортувати перестановку для кожної з множин.
Група 2. Розмір мінімальної множини, коли не перевищує (якщо обрати , то нескладно відсортувати будь-яку перестановку розміром до ), тому можна перебирати лише множини розміру до та перевіряти чи можна відсортувати перестановку.
Група 3. Є три можливі випадки в залежності від мінімального розміру доброї множини у цьому випадку:
для всіх ;
та ;
Інакше .
За допомогою std::map
можна підтримувати множину всіх значень і перевіряти скільки існує унікальних ненульових значень .
Група 4. Нехай в нас є деяка множина , за допомогою якої ми можемо відсортувати нашу перестановки використовуючи операції з умови.
Розгянемо елемент, що стояв на позиції у початковій перестановці. Очевидно, що у тотожній перестановці він знаходиться на позиції . Розглянемо послідовність позицій на яких побував елемент перестановки зі значенням перед тим як перейти на фінальну позицію:
.
при чому , де для таких , що .
Виразимо через : . Тоді маємо, що
.
Тобто маємо, що щоб переставити елемент зі значенням на свою позицію необхідно, щоб ксорами елементів множини можна було представити число для кожного : .
Пригадаємо XOR базис. XOR базис — це мінімальний набір чисел, які можуть представляти будь-яке число заданої множини за допомогою комбінацій XOR. Детальніше можна дізнатися тут.
Нескладно довести, що якщо взяти як XOR базис чисел побудований алгоритмом наведеним нижче, то це і буде одна з множин мінімального розміру, якою можна відсортувати задану перестановку.
vector <int> basis; void add (int x) { for (int i : basis) { x = min(x, x ^ i); } if (x) { for (int &i : basis) { i = min(i, i ^ x); } basis.push_back(x); } }
Тоді відповіддю на кожен запит є розмір XOR базису побудованого на числах .
Тоді після кожного запиту можемо за порахувати розмір XOR базису та вивести його. Складність розв'язку: .
Група 5. За домогою дерева відрізків можна підримувати XOR базис масиву за на запит. В кожній вершині будемо зберігати XOR базис чисел за які відповідає відповідний сегмент дерева відрізків.
Об'єднувати два базиси можна в лоб за . Тоді операція оновлення буде працювати за .
Група 6. Коли , то ми знаємо всі запити наперед. До XOR базису ми можемо додавати елементи. Але, на жаль, не можемо видаляти. Маючи все це можемо використати цю техніку, яка дозволяє видаляти із структури, в яку можемо додавати, якщо запити дано наперед.
Група 7.
Як підтримувати XOR базис в онлайні за на запит можна дізнатися за посиланням.