BOJ 31294 Convolution

BOJ 31294 Convolution

문제 링크:

문제 내용

길이 2n2^n의 배열 ffgg가 주어집니다. 다음의 식으로 정의되는 배열 hh를 구하세요. 식에서 jkj | kjjkk의 bitwise OR를 의미합니다.

h(i)=jk=if(j)g(k) h(i) = \sum_{j|k = i} f(j) g(k)

입력

첫 줄에는 nn의 값과 테스트 케이스의 개수 tt가 주어집니다. (1n161 \le n \le 16, 1t1001 \le t \le 100)

그 다음 줄에는 각 테스트 케이스를 생성할 파라미터 값 aabb가 주어집니다. (1a,b1091 \le a, b \le 10^9)

aabb의 값을 이용하는 PRNG 함수 rand16을 다음과 같이 정의합시다.

state = 0
def rand16():
    global state
    state = (state * a + b) % (2 ** 32)
    return state >> 16

그러면 각각의 테스트 케이스에 대해, 먼저 rand162n2^n번 호출하여 순서대로 배열 ff의 원소를 얻고, 그 다음 rand162n2^n번 호출하여 순서대로 배열 gg의 원소를 얻어야 합니다. state는 테스트 케이스 사이에 초기화되지 않습니다.

출력

각 테스트 케이스에 대해, (i=02n1h(i)×(i+1))mod232(\sum_{i = 0}{2^n-1} h(i) \times (i+1)) \bmod 2^{32}를 출력합니다.

문제 풀이

스포일러

OR convolution의 기본 문제입니다. 이 문제는 다음의 과정을 거쳐서 풀 수 있습니다.

  • 먼저 배열 ffgg에 SOS DP를 합니다. 그러면 f(i)f'(i)ii의 1 비트의 부분집합을 1로 갖는 인덱스 jj에 대한 f(j)f(j)의 합입니다.
  • 그 다음, 각각의 ii에 대해 f(i)g(i)f(i)g(i)를 구하여 h(i)h'(i)로 둡니다. 이러한 h(i)h'(i)의 값은 jkj|kii의 1 비트의 부분집합이 되는 jjkk에 대해 f(j)g(k)f(j) g(k)의 합입니다.
  • 마지막으로, 배열 hh'에 비트 포함배제를 하면 hh를 얻을 수 있습니다.
Last updated on