POJ1226---Substrings(后缀数组+二分)
2015-04-07 17:59
393 查看
Description
You are given a number of case-sensitive strings of alphabetic characters, find the largest string X, such that either X, or its inverse can be found as a substring of any of the given strings.
Input
The first line of the input contains a single integer t (1 <= t <= 10), the number of test cases, followed by the input data for each test case. The first line of each test case contains a single integer n (1 <= n <= 100), the number of given strings, followed by n lines, each representing one string of minimum length 1 and maximum length 100. There is no extra white space before and after a string.
Output
There should be one line per test case containing the length of the largest string found.
Sample Input
2
3
ABCD
BCDFF
BRCD
2
rose
orchid
Sample Output
2
2
Source
Tehran 2002 Preliminary
把串,反串都连在一起,求后缀数组,然后二分,给后缀数组分组就行了
You are given a number of case-sensitive strings of alphabetic characters, find the largest string X, such that either X, or its inverse can be found as a substring of any of the given strings.
Input
The first line of the input contains a single integer t (1 <= t <= 10), the number of test cases, followed by the input data for each test case. The first line of each test case contains a single integer n (1 <= n <= 100), the number of given strings, followed by n lines, each representing one string of minimum length 1 and maximum length 100. There is no extra white space before and after a string.
Output
There should be one line per test case containing the length of the largest string found.
Sample Input
2
3
ABCD
BCDFF
BRCD
2
rose
orchid
Sample Output
2
2
Source
Tehran 2002 Preliminary
把串,反串都连在一起,求后缀数组,然后二分,给后缀数组分组就行了
/************************************************************************* > File Name: POJ1226.cpp > Author: ALex > Mail: zchao1995@gmail.com > Created Time: 2015年04月07日 星期二 16时45分07秒 ************************************************************************/ #include <functional> #include <algorithm> #include <iostream> #include <fstream> #include <cstring> #include <cstdio> #include <cmath> #include <cstdlib> #include <queue> #include <stack> #include <map> #include <bitset> #include <set> #include <vector> using namespace std; const double pi = acos(-1.0); const int inf = 0x3f3f3f3f; const double eps = 1e-15; typedef long long LL; typedef pair <int, int> PLL; int pos[22000]; class SuffixArray { public: static const int N = 22000; int init ; int X ; int Y ; int Rank ; int sa ; int height ; int buc ; int LOG ; int dp [20]; int size; bool vis[110]; void clear() { size = 0; } void insert(int n) { init[size++] = n; } bool cmp(int *r, int a, int b, int l) { return (r[a] == r[b] && r[a + l] == r[b + l]); } void getsa(int m = 256) //m一般为最大值+1 { init[size] = 0; int l, p, *x = X, *y = Y, n = size + 1; for (int i = 0; i < m; ++i) { buc[i] = 0; } for (int i = 0; i < n; ++i) { ++buc[x[i] = init[i]]; } for (int i = 1; i < m; ++i) { buc[i] += buc[i - 1]; } for (int i = n - 1; i >= 0; --i) { sa[--buc[x[i]]] = i; } for (l = 1, p = 1; l <= n && p < n; m = p, l *= 2) { p = 0; for (int i = n - l; i < n; ++i) { y[p++] = i; } for (int i = 0; i < n; ++i) { if (sa[i] >= l) { y[p++] = sa[i] - l; } } for (int i = 0; i < m; ++i) { buc[i] = 0; } for (int i = 0; i < n; ++i) { ++buc[x[y[i]]]; } for (int i = 1; i < m; ++i) { buc[i] += buc[i - 1]; } for (int i = n - 1; i >= 0; --i) { sa[--buc[x[y[i]]]] = y[i]; } int i; for (swap(x, y), x[sa[0]] = 0, p = 1, i = 1; i < n; ++i) { x[sa[i]] = cmp(y, sa[i - 1], sa[i], l) ? p - 1 : p++; } } } void getheight() { int h = 0, n = size; for (int i = 0; i <= n; ++i) { Rank[sa[i]] = i; } height[0] = 0; for (int i = 0; i < n; ++i) { if (h > 0) { --h; } int j =sa[Rank[i] - 1]; for (; i + h < n && j + h < n && init[i + h] == init[j + h]; ++h); height[Rank[i] - 1] = h; } } //预处理每一个数字的对数,用于rmq,常数优化 void initLOG() { LOG[0] = -1; for (int i = 1; i < N; ++i) { LOG[i] = (i & (i - 1)) ? LOG[i - 1] : LOG[i - 1] + 1; } } void initRMQ() { initLOG(); int n = size; int limit; for (int i = 0; i < n; ++i) { dp[i][0] = height[i]; } for (int j = 1; j <= LOG ; ++j) { limit = (n - (1 << j)); for (int i = 0; i <= limit; ++i) { dp[i][j] = min(dp[i][j - 1], dp[i + (1 << j) - 1][j - 1]); } } } int LCP(int a, int b) { int t; a = Rank[a]; b = Rank[b]; if (a > b) { swap(a, b); } --b; t = LOG[b - a + 1]; return min(dp[a][t], dp[b - (1 << t) + 1][t]); } bool check(int k, int n) { int cnt = 1; memset(vis, 0, sizeof(vis)); vis[pos[sa[1]]] = 1; for (int i = 1; i < size; ++i) { if (height[i] >= k) { if (!vis[pos[sa[i + 1]]]) { ++cnt; vis[pos[sa[i + 1]]] = 1; } } else { if (cnt == n) { return 1; } memset(vis, 0, sizeof(vis)); vis[pos[sa[i + 1]]] = 1; cnt = 1; } } return 0; } void solve(int n) { int l = 1, r = size, mid, ans = 0; while (l <= r) { mid = (l + r) >> 1; if (check(mid, n)) { l = mid + 1; ans = mid; } else { r = mid - 1; } } printf("%d\n", ans); } }SA; char str[120]; int main() { int t; scanf("%d", &t); while (t--) { int n, maxs = 256, cnt = 0; SA.clear(); scanf("%d", &n); if (n == 1) { scanf("%s", str); int len = strlen(str); printf("%d\n", len); continue; } for (int i = 1; i <= n; ++i) { scanf("%s", str); int len = strlen(str); for (int j = 0; j < len; ++j) { SA.insert((int)str[j]); pos[cnt++] = i; } SA.insert(maxs++); pos[cnt++] = 0; reverse(str, str + len); for (int j = 0; j < len; ++j) { SA.insert((int)str[j]); pos[cnt++] = i; } pos[cnt++] = 0; SA.insert(maxs++); } SA.getsa(maxs); SA.getheight(); SA.solve(n); } return 0; }
相关文章推荐
- POJ 1226 Substrings(后缀数组+二分答案)
- |poj 1226|后缀数组|二分|Substrings
- POJ 1226 Substrings(后缀数组+二分)
- POJ 1226 Substrings 后缀数组
- POJ 1226 Substrings (后缀数组 n个串的最长公共子串)
- 【POJ 1226】Substrings【后缀数组】
- poj 1743 Musical Theme(最长不重叠重复子串 后缀数组+二分)
- 【后缀数组】【二分答案】【差分】poj1743 Musical Theme
- poj 1743 Musical Theme(后缀数组+二分)
- poj1743 Musical Theme(后缀数组--不可重叠最长重复子串+二分)
- poj 3450 Corporate Identity(后缀数组+二分)
- POJ 3261 (后缀数组 二分) Milk Patterns
- poj 3294 Life Forms(后缀数组+二分)
- POJ 1743 Musical Theme(后缀数组+二分)
- POJ-1743-Musical Theme(后缀数组+二分)
- POJ 1743 (后缀数组 二分) Musical Theme
- poj 1226 Substrings(二分 + kmp)
- poj 1226 求多串最长公共子串 或 回文子串 KMP&&strstr&&后缀数组
- POJ 3261 Milk Patterns(后缀数组+二分答案+离散化)
- POJ 1226后缀数组:求出现或反转后出现在每个字符串中的最长子串