BOJ 7038 Cow Patterns

BOJ 7038 Cow Patterns

문제 링크:

문제 내용

1 이상 SS 이하의 정수로 이루어진 길이 NN의 수열 a1,a2,,aNa_1, a_2, \cdots, a_N과 길이 KK의 패턴 b1,b2,,bKb_1, b_2, \cdots, b_K이 있습니다. 수열에서 다음의 조건을 충족하는 길이 KK의 부분 문자열의 위치들을 모두 찾아 출력하세요.

  • 부분 문자열 [ai,ai+1,,ai+K1]=[c1,c2,,cK][a_i, a_{i+1}, \cdots, a_{i+K-1}] = [c_1, c_2, \cdots, c_K]가 있을 때, 모든 1x,yK1 \le x, y \le K에 대해 다음이 성립합니다.
    • cx=cybx=byc_x = c_y \Leftrightarrow b_x = b_y
    • cx<cybx<byc_x < c_y \Leftrightarrow b_x < b_y
    • 즉, 수열에서의 pairwise 대소관계와 패턴의 pairwise 대소관계가 모두 일치합니다.

입력

첫 줄에 NN, KK, SS가 주어집니다. (1N100  0001 \le N \le 100\;000, 1K25  0001 \le K \le 25\;000, 1S251 \le S \le 25)

다음 NN줄에는 수열의 원소들이 한 줄에 하나씩 주어집니다.

다음 KK줄에는 패턴의 원소들이 한 줄에 하나씩 주어집니다.

출력

첫 줄에는 문제의 조건을 충족하는 각각의 부분 문자열의 개수를 출력합니다. 다음 줄부터는 각 부분 문자열의 맨 왼쪽 원소의 인덱스를 한 줄에 하나씩 오름차순으로 출력합니다.

문제 풀이

스포일러

이 문제는 라빈 카프로 풀 수 있습니다. 수열과 패턴을 각각 다음과 같이 SS개의 수열과 SS개의 패턴으로 분리합니다.

  • xi,jx_{i,j} (1iS1 \le i \le S): aj=ia_j = i이면 1, 아니면 0

그리고 SS개의 패턴에 대해 해싱을 진행한 다음 해시값이 0인 것을 모두 제거하면, 패턴의 원소들의 대소관계에 대한 정보가 담긴 해시가 만들어집니다.

이제 같은 방법으로 수열에 대해 길이 KK의 롤링 해시를 진행하면서, 해시값이 0이 아닌 것들을 모았을 때 패턴의 해시와 일치하는지를 확인하면 됩니다.

Last updated on