Автор задачі: | Хайдара Аль Макдід |
Підготовлено: | Хайдара Аль Макдід |
Редагував: | Хасан Салех (MathModel) |
Розв'язок
Ми хочемо максимізувати значення
після вибору точно різних індексів і заміни кожного вибраного a_i на його 32-бітне побітове заперечення \sim a_i. Оскільки береться над 32 бітами, ми можемо розглядати це як \sim x = (2^{32}-1) - x, або, еквівалентно, \sim x = (\texttt{MASK} \,\hat{}\, x) з \texttt{MASK} = 2^{32}-1.
Нехай остаточна відповідь буде . Для кожного біта, який дорівнює в , кожен елемент у фінальному масиві також повинен мати цей біт рівним , інакше AND матиме у цій позиції. Це підказує про побудову жадібно біт за бітом, починаючи з найбільш значущого біта до найменш значущого: ми підтримуємо поточну відповідь ans, і для кожного біта з до ми намагаємося встановити його в поверх того, що ми вже зафіксували.
Конкретно, на біті ми формуємо кандидатне значення
що означає, що ми хочемо, щоб фінальний AND мав усі біти, які дорівнюють у cand. Для цього зафіксованого cand ми проводимо перевірку здійсненності на всьому масиві. Для кожного елемента x = a_i є лише два стани у фінальній конфігурації: або ми зберігаємо його як , або ми перевертаємо його на y = \sim x = (\texttt{MASK} - x). Щоб cand було досяжним, для кожної позиції принаймні один з цих варіантів повинен повністю покривати всі біти cand:
Дивлячись на (\text{keep\_ok}, \text{flip\_ok}), ми ділимо індекси на три корисні типи:
Якщо обидва є хибними, ні , ні не мають усіх бітів cand, тому цей індекс ніколи не може задовольнити cand. Тоді cand сама по собі є неможливою, і ми повинні відхилити цей біт.
Якщо \text{keep\_ok} = \text{false} і \text{flip\_ok} = \text{true}, ми змушені перевернути цей індекс, щоб задовольнити cand. Нехай буде кількість таких змушених індексів.
Якщо \text{keep\_ok} = \text{true} і \text{flip\_ok} = \text{true}, цей індекс є гнучким: як збереження, так і перевертання все ще задовольняють cand. Нехай буде кількість таких гнучких індексів.
(Коли \text{keep\_ok} = \text{true} і \text{flip\_ok} = \text{false}, ми просто повинні зберегти елемент; це не споживає жодного перевертання і не дає жодної гнучкості.)
Ми повинні виконати точно перевертів загалом. Для фіксованого cand усі змушені індекси повинні бути перевернуті, тому нам потрібно принаймні перевертів. З іншого боку, ми можемо за бажанням перевернути будь-яку підмножину з гнучких індексів, тому загальна кількість перевертів, які ми можемо реалізувати, залишаючи cand задовольняти, коливається від (тільки змушені) до F+C (змушені плюс усі гнучкі). Отже, cand є здійсненним, якщо і тільки якщо
Якщо ця нерівність виконується, ми знаємо, що існує спосіб вибрати точно індексів для перевертання так, щоб кожен фінальний елемент покривав усі біти cand. У цьому випадку ми приймаємо цей біт і встановлюємо \texttt{ans} := \texttt{cand}. Якщо ні, ми залишаємо біт на в ans і переходимо до наступного нижчого біта.
Оскільки ми обробляємо біти з найбільш значущого вниз і встановлюємо біт лише тоді, коли існує якась конфігурація з точно перевертаннями, яка підтримує всі вибрані біти до цього моменту, отримане ans є лексикографічно (а отже, чисельно) максимальним фінальним AND, який можна досягти. Для кожної з позицій біта ми скануємо всі елементів один раз, тому загальна складність становить O(32n) = O(n) за часом і додаткової пам'яті, крім масиву вхідних даних.
n,k=map(int, input().split())
a=list(map(int, input().split()))
MASK=(1<<32)-1
ans=0
for j in range(31, -1, -1):
p=1<<j
cand = ans | p
forced = 0
flex = 0
ok = True
for x in a:
keep = (x & cand) == cand
flipped = (~x) & MASK
flip = (flipped & cand) == cand
if not keep and not flip:
ok = False
break
if not keep and flip:
forced += 1
elif keep and flip:
flex += 1
if not ok:
continue
rem = k - forced
if rem < 0 or rem > flex:
continue
ans = cand
print(ans)