
문제 https://www.acmicpc.net/problem/3080 알고리즘 Trie 풀이 관찰이 필요한 문제입니다. 예제들을 그림으로 그려 예제 입출력을 이해하도록 합시다. 이를 통해 문제의 답은 (트라이의 자식 수 + 해당 트라이에서 끝나는 단어)의 팩토리얼들의 곱이라는 점을 알아낼 수 있습니다. 이렇게 문제를 풀게 되면 메모리 초과가 발생하게 됩니다. Trie? 선형시간에 원하는 문자열을 찾아낼 수 있는 자료구조입니다. 이를 가능케 하는 것은 각각의 트라이마다 모든 문자들을 가리키는 포인터를 저장하고 있기 때문입니다. 이 때문에 많은 메모리를 사용한다는 단점이 있는 자료구조입니다. 따라서, 필요하지 않은 문자열을 제거해야합니다. Suffix Array & LCP에서 봤듯이, 주어진 문자열을 정렬..

문제 https://www.acmicpc.net/problem/9249 알고리즘 Suffix Array 풀이 LCS문제입니다. 주어진 두 문자열$A, B$를 합친 후 LCP를 구하게 되면 답을 얻을 수 있습니다. 이때 주의해야 할 점이 있습니다. 인접한 LCP를 검사할 때, 하나의 Suffix는 $A$의 일부를 포함해야 하지만, 나머지 Suffix는 $A$를 포함해선 안된다는 점입니다. 이점을 유의하지 않으면 $A$ 또는 $B$ 내에서만 LCP를 뽑아버리므로 두 문자열의 공통부분 문자열을 얻지 못하게 됩니다. 시간 복잡도는 Suffix Array와 LCP를 구해야 하므로 $O(NlogN+N)$입니다. 코드 #include #define rep(i,n) for(int i=0;i

문제 https://www.acmicpc.net/problem/11479 알고리즘 Suffix Array 풀이 열심히 구한 Suffix Array와 LCP로 우리는 무엇을 할 수 있을까요? 그중 하나인 부분 문자열과 관련된 문제들입니다. 이 문제에선 서로다른 부분 문자열의 개수를 묻고 있습니다. 부분 문자열이란 것은 달리 말하면 Suffix의 Prefix입니다. Banana를 예로 들어보겠습니다. 모든 Suffix를 나열해보면 {Banana,anana,nana,ana,na,a} 가 될 겁니다. 여기서 부분 문자열을 얻기 위해 각각의 Suffix들에 대해 Prefix를 보면 되겠죠. 모든 Suffix 중 Suffix "anana"에서 얻을 수 있는 부분 문자열은 {a,an,ana,anana,anana} 입..

문제 https://www.acmicpc.net/problem/9248 알고리즘 Suffix Array 풀이 문자열에서 가장 어려운 알고리즘인 Suffix Array입니다. 이 글에선 제가 해당 알고리즘을 공부할 때 어려웠던 부분 및 이해하기 위한 선행지식을 간단하게 정리하려고 합니다. Counting sort & Radix sort Counting sort는 non-comparison sort으로 $O(N)$에 정렬을 해주는 알고리즘입니다. 주로 정렬할 데이터에 대한 사전 지식이 있을 때 사용합니다. 사전 지식이란 $k$이하의 정수를 배열을 정렬하라는 문제에서 $k$이하의 정수라는 조건을 의미합니다. 방법은 stable 한 방법과 unstable한 방법이 있는데, 정렬할 데이터가 단일 데이터(정수 1개..

문제 https://www.acmicpc.net/problem/13276 알고리즘 KMP 해설 다양한 풀이가 있는 문제입니다. 라빈 카프를 이용한 해싱, 가장 효율적인 Suffix Array 등 이 있지만 구현이 가장 쉬운 KMP로 풀었습니다. $S$에 대해 두 문자열$A$,$B$가 나타나는 위치를 KMP를 통해 찾은 후, 부분 문자열이 될 수 있는 것들을 담았습니다. $vector$에 직접 부분 문자열을 담게 되면 메모리 초과가 발생하니, $set$을 통해 부분 문자열을 담고, 자연스레 중복도 제거하도록 합시다. 시간 복잡도는 모든 인덱스에서 부분 문자열이 시작하고 끝날 수 있으므로 $O(N^2)$ + 해시 접근입니다. #include #include #define rep(i,n) for(int i=0..

문제 https://www.acmicpc.net/problem/6206 알고리즘 라빈 카프 해설 https://www.acmicpc.net/problem/3033 3033번 문제에선 두 번 이상 등장하는 패턴 중, 가장 긴 문자열의 길이를 물었지만, 이 문제는 두 번이 아닌 $K$번 등장하는 패턴을 묻고 있습니다. 등장 횟수를 카운트하기 위하여 $set$ 대신 $map$을 사용한 것을 제외하곤 3033번 문제와 동일하게 풀 수 있습니다. ++ 각 우유 샘플이 100만 이하의 정수를 가질 수 있으므로, $BASE$는 100만 이상의 값을 주도록 합시다. 코드 #include #include #define rep(i,n) for(int i=0;i> K; rep(i, N) cin >> arr[i]; int l..

문제 https://www.acmicpc.net/problem/17228 알고리즘 라빈 카프 해설 정원의 쉼터가$N-1$개의 길로 연결되어있다는 점에서 트리임을 알 수 있고, 반대방향으로 이동하는 것을 금지한다는 조건에서 DFS접근방식을 생각했습니다. 만영이 취향의 문자열을 해싱한 후, DFS를 수행하며 수행과정에서 얻는 문자열 또한 해싱하며, 해시값이 동일하다면 정답을 카운트해주면 됩니다. 처음 $recur()$ 에서는 롤링 해시할 길이가 없으므로, 가짜 문자인 $를 넣어주었습니다. DFS와 라빈 카프를 이용했으므로 시간 복잡도는 $O(V+E+N)$입니다. 코드 #include #include #define rep(i,n) for(int i=0;i N; adj.resize(N); rep(i, N - 1..

문제 https://www.acmicpc.net/problem/3033 알고리즘 라빈 카프 풀이 https://www.acmicpc.net/problem/1701 길이 제한을 제외하고, 위 문제와 동일합니다. 우리는 1701번 문제를 $O(N^2)$에 해결했지만, 이 문제는 길이 제한이 20만 이므로 다른 전략을 택하도록 합시다. 만약 길이$m$인 문자열이 두 번 이상 등장한다고 해봅시다. 그러면 $m$보다 작은 $n$은 두 번 이상 등장함을 알 수 있을까요? 네. 이는 너무나도 확실합니다. 예를 들어 문자열 $aabaa$에서 부분 문자열 $aa$는 두번 등장함을 알 수 있고, 이보다 짧은$a$는 $aa$가 등장한 인덱스를 제외하고도 더 등장할 수가 있죠. 그렇다면 길이$m$보다 긴 길이$k$는 몇 번 ..
- Total
- Today
- Yesterday
- knapsack
- bfs
- spring
- kmp
- 2-SAT
- 트라이
- 스위핑
- 이분탐색
- greedy
- 동적계획법
- spring boot
- string
- Fenwick
- 정렬
- 이분매칭
- hld
- dfs
- sorting
- DP
- sweeping
- Suffix Array
- implementation
- Oracle
- Segment tree
- union find
- 좌표압축
- dijkstra
- 세그먼트트리
- SCC
- 펜윅트리
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |