Задача Bitwise AND

В задаче Bitwise ANDopen in new window дано множество чисел [latex]S = \{1, 2, 3, ..., N\}[/latex], нужно найти два числа [latex]A[/latex] и [latex]B[/latex] такие что значение [latex]A \& B[/latex] (побитовый оператор И) наибольшее, но меньше заданного [latex]K[/latex]. Вывести наибольшее возможное [latex]A \& B[/latex].

Ограничения:

  • [latex]2 \leq N \leq 10^3[/latex]
  • [latex]2 \leq K \leq N[/latex]

Решение

Решение с перебором рабочее, но не проходит по скорости: всего пар [latex]N * (N - 1)[/latex], сложность получается [latex]O(n^2)[/latex].

У этой задачи есть решение за константное время. Предположим число [latex]K[/latex] нечётное. Это значит что в побитовой записи справа у него находится единица:

[latex]11_{10} = 1011_2[/latex]

Рассмотрим [latex]K-1[/latex], в двоичной записи все его цифры совпадают с [latex]K[/latex] кроме последней в которой находится 0:

[latex]10_{10} = 1010_2[/latex]

Исходя из этого, для нечётного [latex]K[/latex] всегда выполняется равенство [latex](K - 1) \& K = K - 1[/latex].

Так как [latex]N \geq K[/latex] то мы всегда можем взять [latex]A = K - 1[/latex] и [latex]B = K[/latex] и получить максимальный ответ [latex]K - 1[/latex].

Остался случай с чётным [latex]K[/latex]. Если [latex]K[/latex] чётное число, то [latex]K-1[/latex] нечётное, для него можно провести те же самые рассуждения и получить ответ [latex]K-2[/latex]. Но можно ли для чётного [latex]K[/latex] получить ответ [latex]K-1[/latex]?

Рассмотрим детальнее числа входящие в выражение [latex]A \& B[/latex]. Будем исходит из того что в ответе задачи получается число [latex]K-1[/latex], значит либо [latex]A[/latex], либо [latex]B[/latex] равно [latex]K - 1[/latex]. Предположим число [latex]A = K - 1[/latex]. Число [latex]B[/latex] не может быть меньше [latex]A[/latex], так как должно содержать единицы в тех же позициях что и число [latex]A[/latex]. Чтобы [latex]B[/latex] отличалось и было минимальным оно должно содержать дополнительную единицу в самом правом разряде в котором в [latex]A[/latex] содержится 0. Такое число получается при [latex]B = (K - 1) | K[/latex] (побитовое ИЛИ).

По условию задачи [latex]A, B \leq N[/latex]. [latex]A = K - 1[/latex] подходит под это условие, а вот [latex]B = (K - 1) | K[/latex] неизвестно. Пример с числами:

  • [latex]K = 46_{10} = 101110_2[/latex]
  • [latex]K - 1 = 45_{10} = 101101_2[/latex]
  • [latex](K - 1) | K = 101111_2 = 47_{10}[/latex]

При выполнении условия [latex](K - 1) | K \leq N[/latex] получаем что максимально возможное число в ответе [latex]K - 1[/latex]. Если же условие не выполняется, то ответ будет [latex]K - 2[/latex].

Причём чётность числа проверять не обязательно. Решение для чётного [latex]K[/latex] всегда подходит и для нечётного, так как условие [latex](K - 1) | K \leq N[/latex] всегда выполняется для нечётного [latex]K \leq N[/latex].

Код решения на Python:

n, k = [int(x) for x in input().split()]

print(k - 1 if (k - 1) | k <= n else k - 2)
1
2
3
Последниее изменение: 24.08.2023, 06:42:55