POJ1226---Substrings(后缀数组+二分)
来源:互联网 发布:云计算入门书籍 编辑:程序博客网 时间:2024/05/17 02:53
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
把串,反串都连在一起,求后缀数组,然后二分,给后缀数组分组就行了
/************************************************************************* > 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[N]; int X[N]; int Y[N]; int Rank[N]; int sa[N]; int height[N]; int buc[N]; int LOG[N]; int dp[N][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[n]; ++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;}
- POJ1226---Substrings(后缀数组+二分)
- [POJ1226]Substrings(后缀数组+二分)
- Substrings poj1226 (后缀数组)
- poj1226 Substrings 后缀数组
- POJ1226:Substrings(后缀数组)
- 后缀数组poj1226
- POJ 1226 Substrings(后缀数组+二分)
- |poj 1226|后缀数组|二分|Substrings
- poj 1226 Substrings (二分+后缀数组)
- poj1226(kmp算法,后缀数组)
- POJ1226 Substrings
- poj1226 Substrings
- POJ1226--Substrings
- poj1226--Substrings
- POJ1226-Substrings
- POJ-1226(后缀数组)(Substrings)
- spoj 694 Distinct Substrings(后缀数组)
- SPOJ 694 Distinct Substrings(后缀数组)
- 输入电阻和输出电阻
- Zephir - 高效开发PHP扩展
- 个人学习Java的心得体会
- tcp/ip ---------- ARP协议
- rpm和rpmbuild
- POJ1226---Substrings(后缀数组+二分)
- iOS开发~CocoaPods使用详细说明
- Golang:生成n个从a到b不重复的随机数
- 机器学习开源工具及licence
- TeamTalk--Android-IM架构设计
- ordfilt2函数举例
- MSS与MTU的关系
- Android 设计模式
- 第二章 — 4