hdu2328 后缀树
#include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #include <queue> #include <stack> #include <deque> #include <iostream> using namespace std; typedef long long LL; const int MOD = 1000000007; const int maxn = 40009 + 5; int tree[maxn][30]; int sum[maxn]; int tot; char ss[maxn], mid[maxn], ans[maxn]; void insert(char *str) { int len = strlen(str); int root = 0; for (int i = 0; i < len; i++) { int id = str[i] - 'a'; if (!tree[root][id]) tree[root][id] = ++tot; if (sum[tree[root][id]] + 1 >= 1) { sum[tree[root][id]] = 1; } else { break; } root = tree[root][id]; } } int find(char *str, int x) { int len = strlen(str); int root = 0, deep = 0; for (int i = 0; i < len; i++) { int id = str[i] - 'a'; if (tree[root][id]) { if (sum[tree[root][id]] + 1 >= x) { sum[tree[root][id]] = x; deep++; } else { break; } root = tree[root][id]; } else { break; } } return deep; } int main() { int n, i, j, k, head; while (scanf("%d", &n) != EOF) { if(n == 0) break; memset(tree, 0, sizeof(tree)); memset(sum, 0, sizeof(sum)); memset(ans, 0, sizeof(ans)); tot = 1; for (i = 1; i < n; i++) { scanf(" %s", ss); k = strlen(ss); //cout << "input: " << ss << endl; if (i == 1) { for (j = 0; j < k; j++) { // printf("%s\n", &ss[j]); insert(&ss[j]); } } else { for (j = 0; j < k; j++) { find(&ss[j], i); } } } head = 0; scanf(" %s", ss); //cout << "Nth: " << ss << endl; k = strlen(ss); // cout << "follows " << endl; for (j = 0; j < k; j++) { // cout << &ss[j] << endl; int len = find(&ss[j], n); mid[0] = 0; strncpy(mid, ss + j, len); mid[len] = 0; // printf("mid: %s\n", mid); if (len > head || (len == head && strcmp(mid, ans) < 0)) { head = len; ans[0] = 0; strcpy(ans, mid); // printf("ans: %s\n", ans); } } if (head == 0) { printf("IDENTITY LOST\n"); } else { printf("%s\n", ans); } // cout << " n: " << n << endl; } return 0; }
后缀树的思想和字典树一样,不过是依次把字符串的所有后缀加入到树中。
需要整理的知识:后缀树的O(n)优化、后缀自动机、后缀数组