Іспит

Рішення, яке працює для $$$n \le 20$$$. Будемо перебирати елементи, які візьмемо у множину за $$$2^n$$$ за допомогою біт-масок (схожа ідея була у другій задачі першого туру III етапу Всеукраїнської олімпіади з програмування). Коли ми обрали множину, будемо знаходити її значення побітового АБО, мінімум та максимум — $$$val$$$, $$$mn$$$ та $$$mx$$$ відповідно. Якщо popcount(val)$$$ \ge k$$$ будемо оновлювати відповідь: $$$ans = \min(ans, mx - mn)$$$.

Рішення, яке працює для $$$a_i < 1024$$$. Можна відштовхуватися від того, що існує $$$1024$$$ різних значень $$$a_i$$$. Залишимо по одному входженню кожного значення в масив $$$a$$$ (якщо воно було) та відсортуємо масив за зростанням. Побачимо, що на такому масиві нам вигідно обирати його підвідрізкі, а не підпослідовності. Припустимо, що ми обрали два елементи з мінімальним та максимальним значеннями — $$$a_l$$$ та $$$a_r$$$ відповідно. Тобто, його ціна вже є фіксованою. Якщо ми будемо брати елементи, які не будуть збільшувати максимум, чи зменшувати мінімум, його ціна не зміниться. Очевидно, що popcount$$$(a|b) \ge \max$$$(popcount$$$(a)$$$,popcount$$$(b))$$$, де $$$|$$$ позначає побітове АБО. А отже, можна брати усі елементи з індексами $$$l \le i \le r$$$.

Будемо перебирати усі підвідрізки та оновлювати відповідь за $$$\mathcal{O}(m^2)$$$, де $$$m$$$ — розмір масиву після видалення повторюваних елементів.

Повне рішення використовує ідею з попереднього рішення. Відсортуємо масив за зростанням та будемо розглядати його підвідрізки. Можна помітити, що якщо не підходив відрізок $$$(l;r)$$$, то відрізок $$$(l+1;r)$$$ теж не буде підходить. Це натякає на два вказівники, але як рахувати значення побітового АБО на відрізку? З означення побітового АБО, $$$i$$$-й біт буде дорівнювати $$$1$$$, якщо він дорівнює $$$1$$$ хоча б в одному числі, серед яких береться побітове АБО. Можемо зберігати для кожного біта скільки разів він зустрічається на відрізку, а значення побітового АБО можна відновити з цих значень — якщо цей біт зустрічався на відрізку, то цей біт буде й у значенні побітового АБО. Зсуваємо праву границю вправо, доки відрізок не підходить, оновлюємо відповідь і видаляємо найлівіший елемент з відрізка.

Отже, асимптотика — $$$\mathcal{O}(n \log A)$$$, де $$$A$$$ — максимальне значення $$$a_i$$$.

Автор усіх задач: Андрій Столітній.