문제 링크
- http://icpc.me/10066
문제 출처
- 2014 APIO 1번
사용 알고리즘
- manacher
- tree
- hashing
시간복잡도
- $O(N log N)$
- unordered map 이용시 O(N)
풀이
manacher를 돌려주고 시작합시다. manacher를 이용하면 팰린드롬인 구간을 모두 알아낼 수 있습니다. 팰린드롬인 구간은 최대 $O(N^2)$개입니다.
해싱을 하고 map을 이용해서 각 팰린드롬이 나오는 횟수를 계산해주면 $O(N^2 log N)$에 풀 수 있습니다. unordered_map을 이용하면 $O(N^2)$에 풀 수 있습니다.
어떤 문자열에서 서로 다른 팰린드롬의 개수는 최대 N개라는 것을 이용해서 이 풀이를 $O(N log N)$으로 줄일 수 있습니다.Br>
[s, e]가 팰린드롬이면 [s+1, e-1]도 팰린드롬입니다. [s, e]의 해시값을 [s+1, e-1]의 해시값과 연결해줍시다. [s+1, e-1]은 [s+2, e-2]와, [s+2, e-2]는 [s+3, e-3]…을 반복해서 이미 존재하는 해시값이 나올 때까지 반복해서 간선을 만들어줍시다.
이렇게 트리(포레스트)를 만들면 최대 N개의 정점이 생성됩니다.
팰린드롬인 구간 [s, e]가 등장할 때마다 [s, e]의 조상들의 등장 횟수를 각각 1씩 증가시키면 당연히 $O(N^2)$입니다.
하지만 그럴 필요 없이, [s, e]에만 체크를 해줘도 dfs를 이용해 서브트리에 속한 각 정점의 등장 횟수를 더해줘도 됩니다.
map을 사용하면 $O(N log N)$, unordered_map을 사용하면 $O(N)$이 됩니다.
전체 코드
1 |
|