公式

B - |{floor(A_i/2^k)}| 解説 by evima


In this explanation, we assume that indices start from \(0\).

First, it is unnecessary to include elements less than \(2^{K-1}\) in \(A\). This is because replacing elements less than \(2^{K-1}\) with their double will result in the same or a higher score. Therefore, we can limit the elements of \(A\) to be between \(2^{K-1}\) and \(2^K-1\).

[1] When \(N \geq 2^{K-1}\)

Since we can include all elements between \(2^{K-1}\) and \(2^K-1\) in \(A\), we can set \(A_i = \max(1, 2^K - 1 - i)\) \((0 \le i < N)\), for example.

[2] When \(N < 2^{K-1}\)

First, let’s consider an upper bound of the score. For \(0 \le x < K\), consider the number of elements that appear as \(\displaystyle \left\lfloor\frac{A_i}{2^k} \right\rfloor\) between \(2^x\) and \(2^{x+1}-1\). For each \(A_i\), there is at most one \(k\) that satisfies \(\displaystyle 2^x \le \left\lfloor\frac{A_i}{2^k} \right\rfloor < 2^{x+1}\), so the number of such elements is at most \(N\). On the other hand, there are only \(2^x\) integers between \(2^x\) and \(2^{x+1}\), so the number of elements that appear in this range is at most \(\min(N, 2^x)\). Therefore, by summing over all \(x\), we find that the score has an upper bound of \(\displaystyle 1 + \sum_{x=0}^{K-1}\min(N, 2^x)\).

This upper bound can always be achieved. Specifically, we can construct \(A\) as follows:

  • Set \(A_i\) to the sum of \(2^{K-1}\) and the bit-reversal of \(i\).

“The bit-reversal of \(i\)” means the value obtained by reversing the \((K-1)\)-bit binary representation of \(i\).

For example, if \(K=6\) and \(i=6\), then \(i=00110_{(2)}\), so the bit-reversal of \(i\) is \(01100_{(2)}\), which is \(12\).

By implementing the above, we can solve this problem. The time complexity is \(O(NK)\) due to the bit-reversal calculation being the bottleneck.

Sample Implementation (Python3)

for _ in range(int(input())):
    N, K = map(int, input().split())

    def bit_reversal(x):
        return int(bin(x)[2:].zfill(K - 1)[::-1], 2)

    if N >= 2 ** (K - 1):
        print(*[max(1, 2**K - i - 1) for i in range(N)])
    else:
        print(*[2 ** (K - 1) + bit_reversal(i) for i in range(N)])

Additionally, you can also solve it by constructing from the highest bit downwards. See the implementation example below for details.

Sample Implementation (Python3)

for _ in range(int(input())):
    N, K = map(int, input().split())
    C = [1]
    for _ in range(1, K):
        D = [2 * c for c in C] + [2 * c + 1 for c in C]
        C = D[:N]
    while len(C) < N:
        C.append(1)
    print(*C)

投稿日時:
最終更新: