알고리즘 블로그
Published 2026. 3. 14. 17:31
kmp 인사이트 PS 기록들

싸지방에서 코포 치다가 kmp를 만났다.

사회에 있을 때도 많이 안 해봐서 서툴렀던 건데, 이 참에 제대로 기록해두려고 한다.

 

kmp는 에디터를 켜서 주어진 문자열의 모든 prefix를 적고 그 안에서 ctrl + f를 하는 느낌이다.

 

문자열 "ababacabababc"를 상상해보자.

 

윗쪽은 이럴 것이다:

빨간 부분이 윗쪽에서 ctrl + f 했을 때 선택될 수 있는 영역을 나타낸다.

 

빨간 부분을 쭉 사용하다가, "ababab"가 나오며 흐름이 끊긴걸 확인할 수 있다.

하지만 여기서 재활용을 하는데, "abab"로 이어갈 수 있기 때문이다.

 

근데 "abab"를 써먹을 수 있음을 amortized O(1)에 어떻게 확인할텐가?

"ababa"의 뒷부분의 빨간 영역을 새로 따라가서 연장 가능함을 확인하면 된다.

 

그래서 선택된 영역을 두 칸 줄이게 된다.

선택된 범위는 줄어들거나, 1씩 늘어나기만 한다.

amortized O(n)이라는 의미이다.

 

"ababacababab" FAIL "ababab" OK

이런 느낌?

 

 

느낌은 이렇게 기억해두고...

$\pi(i) := \max \{k | k<i \text{ and } S[1 : k] = S[k-i+1 : n] \}$라고 정의를 잘 해보자.

 

코드는 그럼 다음과 같이 짤 수 있게 된다.

ll drag = 0;
border[0] = -1;
border[1] = 0;
            
for(int i=2; i<=n; ++i) {
    while (drag>=0 && a[drag+1] != a[i]) {
        drag = border[drag];
    }
    if (drag>=0)
        border[i] = ++drag;
    else
        border[i] = drag = 0;
}

 

'PS 기록들' 카테고리의 다른 글

26.04.23 ~ 26.05.05 PS  (0) 2026.05.02
최근 PS 기록  (0) 2025.09.24
LGCPC 2025 후기 (검열안됨)  (0) 2025.09.21
Codeforces Round 1051 (Div.2)  (1) 2025.09.18
25.08.06 PS (TOPC 2021)  (0) 2025.08.06
profile

알고리즘 블로그

@도훈.

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!

profile on loading

Loading...