首页 > 代码库 > uva 11107 - Life Forms(后缀数组)
uva 11107 - Life Forms(后缀数组)
题目链接:uva 11107 - Life Forms
题目大意:给定n个字符串,求一个最长的字符串,为n/2个字符串的子串。
解题思路:后缀数组,处理除后缀数组后,二分长度,每次遍历height数组,当长度不足时就分段,如果存在一段中包含n/2个起点,则为可行长度。
#include <cstdio>
#include <cstring>
#include <set>
#include <algorithm>
using namespace std;
const int MAXLEN = 200005;
struct Suffix_Arr {
int n, s[MAXLEN];
int tmp_one[MAXLEN], tmp_two[MAXLEN], c[MAXLEN];
int SA[MAXLEN], rank[MAXLEN], height[MAXLEN];
void init();
void build_arr(int m);
void get_height();
}suf;
int N, maxlen, id[MAXLEN];
void init () {
maxlen = 0;
suf.init();
char word[1005];
for (int i = 0; i < N; i++) {
scanf("%s", word);
if (N == 1) {
printf("%s\n", word);
return;
}
int len = strlen(word);
maxlen = max(maxlen, len);
for (int j = 0; j < len; j++) {
id[suf.n] = i;
suf.s[suf.n++] = word[j];
}
suf.s[suf.n++] = ‘z‘ + i + 1;
}
suf.build_arr(‘z‘ + N + 1);
suf.get_height();
}
bool judge (int l, int flag) {
set<int> vis;
vis.insert(id[suf.SA[0]]);
for (int i = 1; i < suf.n; i++) {
while (i < suf.n && suf.height[i] >= l)
vis.insert(id[suf.SA[i++]]);
if (vis.size() * 2 > N) {
if (flag)
return true;
for (int j = 0; j < l; j++)
printf("%c", suf.s[suf.SA[i-1] + j]);
printf("\n");
}
vis.clear();
vis.insert(id[suf.SA[i]]);
}
return false;
}
void solve () {
if (N == 1)
return;
if (!judge(1, 1)) {
printf("?\n");
return;
}
int l = 1, r = maxlen + 1;
while (l < r) {
int mid = (l + r) / 2;
if (judge(mid, 1))
l = mid + 1;
else
r = mid;
}
judge(l - 1, 0);
}
int main () {
int cas = 0;
while (scanf("%d", &N) == 1 && N) {
if (cas++)
printf("\n");
init();
solve();
}
return 0;
}
void Suffix_Arr::init () {
n = 0;
}
void Suffix_Arr::get_height () {
for (int i = 0; i < n; i++) rank[SA[i]] = i;
int k = 0;
for (int i = 0; i < n; i++) {
if (k) k--;
if (rank[i] == 0)
continue;
int j = SA[rank[i]-1];
while (s[i+k] == s[j+k]) k++;
height[rank[i]] = k;
}
}
void Suffix_Arr::build_arr (int m) {
int *x = tmp_one, *y = tmp_two;
for (int i = 0; i < m; i++) c[i] = 0;
for (int i = 0; i < n; i++) c[x[i] = s[i]]++;
for (int i = 1; i < m; i++) c[i] += c[i-1];
for (int i = n-1; i >= 0; i--) SA[--c[x[i]]] = i;
for (int k = 1; k <= n; k <<= 1) {
int mv = 0;
for (int i = n - k; i < n; i++) y[mv++] = i;
for (int i = 0; i < n; i++) if (SA[i] >= k) {
y[mv++] = SA[i] - k;
}
for (int i = 0; i < m; i++) c[i] = 0;
for (int i = 0; i < n; i++) c[x[y[i]]]++;
for (int i = 1; i < m; i++) c[i] += c[i-1];
for (int i = n-1; i >= 0; i--) SA[--c[x[y[i]]]] = y[i];
swap(x, y);
mv = 1; x[SA[0]] = 0;
for (int i = 1; i < n; i++)
x[SA[i]] = (y[SA[i-1]] == y[SA[i]] && y[SA[i-1] + k] == y[SA[i] + k] ? mv - 1 : mv++);
if (mv >= n)
break;
m = mv;
}
}
uva 11107 - Life Forms(后缀数组)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。