티스토리 뷰
문제
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 <bits/stdc++.h>
#define rep(i,n) for(int i=0;i<n;++i)
#define REP(i,n) for(int i=1;i<=n;++i)
#define FAST cin.tie(NULL);cout.tie(NULL); ios::sync_with_stdio(false)
using namespace std;
string A, B, C;
int al, bl, idx, ans;
vector<int> g, ng, ordered, lcp, cnt, sfx;
void getsfx(string& s) {
int p = 1;
int n = s.size();
int mx = max(257, n + 1);
g.resize(n + 1); ng.resize(n + 1);
sfx.resize(n); ordered.resize(n);
for (int i = 0;i < n;++i) g[i] = s[i];
for (int t = 1;t < n;t <<= 1) {
cnt.clear(); cnt.resize(mx);
for (int i = 0;i < n;++i) ++cnt[g[min(i + t, n)]];
for (int i = 1;i < mx;++i) cnt[i] += cnt[i - 1];
for (int i = n - 1;i >= 0;--i) ordered[--cnt[g[min(i + t, n)]]] = i;
cnt.clear(); cnt.resize(mx);
for (int i = 0;i < n;++i) ++cnt[g[i]];
for (int i = 1;i < mx;++i) cnt[i] += cnt[i - 1];
for (int i = n - 1;i >= 0;--i) sfx[--cnt[g[ordered[i]]]] = ordered[i];
if (p == n) break;
p = 1;
auto cmp = [&](int i, int j) {
if (g[i] == g[j]) return g[i + t] < g[j + t];
return g[i] < g[j];
};
ng[sfx[0]] = 1;
for (int i = 1;i < n;++i) {
if (cmp(sfx[i - 1], sfx[i])) ++p,ng[sfx[i]] = ng[sfx[i - 1]] + 1;
else ng[sfx[i]] = ng[sfx[i - 1]];
}
g = ng;
}
lcp.resize(n);
for (int i = 0;i < n;++i) g[sfx[i]] = i;
for (int i = 0, k = 0;i < n;++i, k = max(k - 1, 0)) {
if (g[i] == n - 1) continue;
for (int j = sfx[g[i] + 1];s[i + k] == s[j + k];++k);
lcp[g[i]] = k;
}
for (int i = 0;i < n - 1;++i) {
if (sfx[i] < al && al < sfx[i + 1]||sfx[i+1]<al&&al<sfx[i]) {
if (lcp[i] <= al) {
if (ans < lcp[i]) {
ans = lcp[i];
idx = sfx[i];
}
}
}
}
}
int main() {
FAST;
cin >> A >> B;
al = A.size();
bl = B.size();
C = A + '$' + B;
getsfx(C);
cout << ans<<'\n';
cout << C.substr(idx, ans);
return 0;
}
'Algorithm' 카테고리의 다른 글
[백준 5446] 용량 부족 (0) | 2020.07.24 |
---|---|
[백준 3080] 아름다운 이름 (0) | 2020.07.21 |
[백준 11479] 서로 다른 부분 문자열의 개수 2 (0) | 2020.07.19 |
[백준 9248] Suffix Array (2) | 2020.07.18 |
[백준 13276] Prefix와 Suffix (0) | 2020.07.17 |
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- 좌표압축
- spring boot
- Oracle
- dijkstra
- Segment tree
- bfs
- hld
- kmp
- 정렬
- 동적계획법
- spring
- dfs
- 2-SAT
- union find
- 이분매칭
- Suffix Array
- 세그먼트트리
- implementation
- SCC
- knapsack
- greedy
- 스위핑
- DP
- sweeping
- Fenwick
- sorting
- 펜윅트리
- 이분탐색
- 트라이
- string
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 29 | 30 |
글 보관함