Найти число массивов с суммой XOR, равной нулю - PullRequest
1 голос
/ 13 апреля 2020

Как определить количество массивов длины N, удовлетворяющих следующим двум условиям:

  1. Каждое значение массива находится в диапазоне от 0 до 5 включительно.
  2. XOR сумма всех значение массива равно 0.

Пример : Позвольте N = 2

, тогда общее количество массивов с суммой XOR равно нулю = 6

, которые являются (0, 0) (1, 1) (2, 2) (3, 3) (4, 4) (5, 5)

Так как же это эффективно выяснить?

1 Ответ

4 голосов
/ 13 апреля 2020

Это можно сделать в O (N) с использованием dynamici c, программируя .

Допустим, dp[i][j] - это ряд массивов, таких, что они имеют i элементов и их XOR-сумма равна j.

Обратите внимание, что 0 <= j <= 7, потому что если N == 6 array [1, 2, 4, 4, 2, 1] соответствует, но его префикс [1, 2, 4] имеет XOR-сумму 7. Кроме того, вы не можете получить сумму XOR больше 7, потому что все числа в диапазоне от 0 до 5 не могут иметь никаких других терминов, кроме 2 ^ 2, 2 ^ 1 и 2 ^ 0, когда разложены в степени 2.

Вот формула для вычисления dp[i][j] с использованием ранее вычисленных значений:

dp[i][j] = 0
# k is XOR-sum of previously calculated number of arrays of length i-1.
for k in range(0, 8):
    # x is a number we append to arrays of length i-1 so XOR-sum is j.
    x = j xor k
    if x <= 5:
        dp[i][j] += d[i - 1][k]

И это остаток кода:

# Assume there's a two dimensional array of integers dp of size N+1 x 8.

# Dynamics initialization.
# There's only one possible array of length 0: []. It's XOR-sum is 0.
dp[0][0] = 1 
for i in range(1, 8):
    dp[0][i] = 0

# Dynamics state calculation.
for i in range(1, N+1):
    for j in range(0, 8):
        # Here comes code from above.
        dp[i][j] = 0
        for k in range(0, 8):
            x = j xor k
            if x <= 5:
                dp[i][j] += d[i - 1][k]

# Answer is dp[N][0].
print(dp[N][0])

Расчет состояния динамики составляет N * 8 * 8 итераций, поэтому сложность составляет O (N) (обратите внимание, что, несмотря на линейную сложность, константа 64 может быть довольно большой).

Есть способ сделать это должно быть вычислено в O (log N) с использованием матричного двоичного возведения в степень . Вкратце: вам нужно вычислить матрицу 8x8 M, показывающую, как значения dp[i-1][*] превращаются в значения dp[i][*]; затем вычислите dp[0] * M^N, где dp[0] равно [1, 0, 0, 0, 0, 0, 0, 0] (точно так же, как при инициализации динамики).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...