정의와 목표
문자열 \(s\) 의 접미사 오토마톤(SAM) 은 \(s\) 의 모든 부분 문자열을 인식하는 최소 DFA다. 놀랍게도 상태 수가 \(O(n)\), 전이 수가 \(O(n)\) 이며 \(O(n)\) 에 온라인으로 구성된다. 서로 다른 부분 문자열 개수, 최장 공통 부분 문자열, \(k\)번째 부분 문자열 등 부분 문자열 문제를 일괄 처리한다.
endpos 동치류
부분 문자열 \(t\) 의 등장 끝 위치 집합을 \(\mathrm{endpos}(t)\) 라 하자. 두 부분 문자열이 같은 endpos 집합을 가지면 한 상태로 묶인다. 한 상태가 표현하는 부분 문자열들은 길이가 연속 구간 \([\,len(\text{link}) + 1,\ len\,]\) 을 이루며, 서로 접미사 관계다. 상태 수가 \(O(n)\) 인 이유가 이 동치류의 개수 한계에 있다.
suffix link
상태 \(v\) 의 suffix link \(link(v)\) 는 "\(v\) 가 표현하는 가장 짧은 부분 문자열의 한 글자 짧은 접미사" 가 속한 상태를 가리킨다. suffix link들은 \(O(n)\) 개 노드의 트리(link tree)를 이루며, 이 트리는 사실상 \(s\) 의 역순 문자열의 접미사 트리와 동형이다. 많은 응용이 이 link tree 위의 트리 DP로 풀린다.
온라인 구성
문자를 하나씩 끝에 붙이며 상태를 늘린다. 현재 끝 상태 last 에서 새 글자 \(c\) 로의 전이를 따라 올라가며:
- 전이가 없으면 새 상태로 연결,
- 전이가 있으면 길이 조건에 따라 상태 복제(clone) 가 필요할 수 있다.
clone은 "이미 존재하는 상태가 새 글자 때문에 endpos가 갈라질 때" 길이만 줄인 사본을 만들어 link 구조를 보정한다. 각 글자 추가가 amortized \(O(1)\) (알파벳 상수) 이라 전체 \(O(n)\).
핵심 사실 요약
| 항목 | 값 |
|---|---|
| 상태 수 | \(\le 2n-1\) |
| 전이 수 | \(\le 3n-4\) |
| 서로 다른 부분 문자열 수 | \(\sum_v (len(v) - len(link(v)))\) |
| 어떤 부분 문자열의 등장 횟수 | link tree 서브트리의 endpos 크기 |