Problem:


Score : 2300 points

Problem Statement

You are given a set S of strings consisting of 0 and 1, and an integer K.

Find the longest string that is a subsequence of K or more different strings in S.
If there are multiple strings that satisfy this condition, find the lexicographically smallest such string.

Here, S is given in the format below:

The data directly given to you is an integer N, and N+1 strings X_0,X_1,...,X_N. For every i (0\leq i\leq N), the length of X_i is 2^i.

For every pair of two integers (i,j) (0\leq i\leq N,0\leq j\leq 2^i-1), the j-th character of X_i is 1 if and only if the binary representation of j with i digits (possibly with leading zeros) belongs to S. Here, the first and last characters in X_i are called the 0-th and (2^i-1)-th characters, respectively.

S does not contain a string with length N+1 or more.

Here, a string A is a subsequence of another string B when there exists a sequence of integers t_1 < ... < t_{|A|} such that, for every i (1\leq i\leq |A|), the i-th character of A and the t_i-th character of B is equal.

Constraints

0 \leq N \leq 20

X_i(0\leq i\leq N) is a string of length 2^i consisting of 0 and 1.

1 \leq K \leq |S|

K is an integer.

Input

Input is given from Standard Input in the following format:

N K
X_0
:
X_N

Output

Print the lexicographically smallest string among the longest strings that are subsequences of K or more different strings in S.

Sample Input 1

3 4
1
01
1011
01001110

Sample Output 1

10

The following strings belong to S: the empty string, 1, 00, 10, 11, 001, 100, 101 and 110.
The lexicographically smallest string among the longest strings that are subsequences of four or more of them is 10.

Sample Input 2

4 6
1
01
1011
10111010
1101110011111101

Sample Output 2

100

Sample Input 3

2 5
0
11
1111

Sample Output 3

The answer is the empty string.



Sample input:
3 4
1
01
1011
01001110


Sample output:
10

Submission status: Accepted

Solution code:
R=range;N,K=map(int,input().split());Q=R(N+1);d=[[0]*2**i for i in Q];f=[[0]*2**i for i in Q]
for i in Q:
 for j,c in enumerate(input()):d[i][j]=int(c)
for i in R(1,N+1):
 for j in R(1<<i):
  t=j>>i-1&1;r=0
  while r<i and j>>i-1-r&1==t:r+=1
  f[i][j]=r
for i in Q:
 for k in R(i+1,N+1):
  z=k-i;m=(1<<z)-1
  for j in R(1<<k):
   d[i][j>>z]+=d[k][j];r=f[z][j&m]
   if r!=z:d[k-r][j>>z<<z-r|j&(1<<z-r)-1]+=d[k][j]
 for j in R(1<<i):
  if d[i][j]>=K:I=i;J=j;break
print(''if I==J==0else bin(J)[2:].zfill(I))

Submission status: Accepted

Solution code:
R=range;N,K=map(int,input().split());Q=R(N+1);d=[[0]*2**N for _ in Q];f=[[0]*2**N for _ in Q]
for i in Q:
 for j,c in enumerate(input()):d[i][j]=int(c)
for i in R(1,N+1):
 for j in R(1<<i):
  t=j>>i-1&1;r=0
  while r<i and j>>i-1-r&1==t:r+=1
  f[i][j]=r
for i in Q:
 for k in R(i+1,N+1):
  z=k-i;m=(1<<z)-1
  for j in R(1<<k):
   d[i][j>>z]+=d[k][j];r=f[z][j&m]
   if r!=z:d[k-r][j>>z<<z-r|j&(1<<z-r)-1]+=d[k][j]
 for j in R(1<<i):
  if d[i][j]>=K:I=i;J=j;break
print(''if I==J==0else bin(J)[2:].zfill(I))

Submission status: Accepted

Solution code:
N, K = map(int, input().split())
D = N + 1

d = [[0] * (1 << N) for _ in range(D)]
f = [[0] * (1 << N) for _ in range(D)]

for i in range(D):
    for j, c in enumerate(input()):
        if c == '1':
            d[i][j] = 1

for i in range(1, D):
    for j in range(1 << i):
        t = (j >> (i - 1)) & 1
        r = 0
        while r < i and ((j >> (i - 1 - r)) & 1) == t:
            r += 1
        f[i][j] = r

for i in range(D):
    for ii in range(i + 1, D):
        z = ii - i
        mask = (1 << z) - 1
        for j in range(1 << ii):
            d[i][j >> z] += d[ii][j]
            r = f[z][j & mask]
            if r != z:
                d[ii - r][((j >> z) << (z - r)) | (j & ((1 << (z - r)) - 1))] += d[ii][j]
    for j in range(1 << i):
        if d[i][j] >= K:
            I = i
            J = j
            break

print('' if I == J == 0 else bin(J)[2:].zfill(I))

Submission status: Accepted

Solution code:
import sys
import numpy as np

def offset(length):
    return 1 << length

def solve():
    n, k = map(int, sys.stdin.buffer.readline().split())
    buf = b"0" + sys.stdin.buffer.read().replace(b"\n", b"")
    table = (np.frombuffer(buf, dtype=np.int8).astype(np.int32) - ord(b"0"))

    offset_table = np.ones(len(table) // 2, dtype=np.int32)
    for v in range(n - 1):
        offset_table[1 << v:2 << v] = 2 << v

    ret = None
    for pos in range(n + 1):
        for length in range(pos + 1, n + 1):
            subtable = table[offset(length):offset(length + 1)]
            table[offset(pos):offset(pos + 1)] += subtable.reshape(-1, 1 << pos, order="F").sum(axis=0)
        count_table = table[offset(pos):offset(pos + 1)]
        index = np.argmax(count_table >= k)
        if count_table[index] >= k: ret = (index, pos)
        else: return ret

        for length in range(pos + 1, n + 1):
            size = 1 << length
            rest = length - pos
            half_period = 1 << (rest - 1)
            trans_table = np.arange(half_period + size, half_period + size * 2, dtype=np.int32) >> rest

            trans_reshaped = trans_table.reshape(-1, half_period * 2)
            trans_reshaped *= np.hstack((offset_table[:half_period], offset_table[half_period - 1::-1]))
            trans_reshaped += np.roll(np.arange(-half_period, half_period), half_period)

            table[trans_table] += table[offset(length):offset(length + 1)]

    return ret


index, length = solve()
print(format(index, "020b")[20 - length:])