cf 427D Match & Catch 后缀数组
2014-05-05 15:30
274 查看
将两个字符串连接,中间加一个没出现的字符,最后添加0。然后从小到大枚举长度ans,对于每个ans,对height数组分组,答案只可能出现在某组内,对每组进行检查,如果只存在两个字符串一个在前一个在后则return true,贴的代码是别人的。
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 100010; char s[maxn]; int sa[maxn]; int t[maxn], t2[maxn], c[maxn]; int rank[maxn], height[maxn]; int l1, l2; void build_sa(int m, int n) { int i, *x = t, *y = t2; for(i = 0; i < m; i++) c[i] = 0; for(i = 0; i < n; i++) c[x[i] = s[i]]++; for(i = 1; i < m; i++) c[i] += c[i-1]; for(i = n-1; i >= 0; i--) sa[--c[x[i]]] = i; for(int k = 1; k <= n; k <<= 1) { int p = 0; for(i = n-k; i < n; i++) y[p++] = i; for(i = 0; i < n; i++) if(sa[i] >= k) y[p++] = sa[i] - k; for(i = 0; i < m; i++) c[i] = 0; for(i = 0; i < n; i++) c[x[y[i]]]++; for(i = 0; i < m; i++) c[i]+= c[i-1]; for(i = n-1; i >= 0; i--) sa[--c[x[y[i]]]] = y[i]; swap(x,y); p = 1; x[sa[0]] = 0; for(i = 1; i < n; i++) x[sa[i]] = y[sa[i-1]] == y[sa[i]] && y[sa[i-1]+k] == y[sa[i]+k] ? p-1 : p++; if(p >= n) break; m = p; } } void getHeight(int n) { int k = 0; for(int i = 0; i <= n; i++) rank[sa[i]] = i; for(int i = 0; i < n; i++) { if(k) k--; int j = sa[rank[i]-1]; while(s[i+k] == s[j+k]) k++; height[rank[i]] = k; } } bool ok(int m, int n) { int cnt1 = 0, cnt2 = 0; for(int i = 1; i <= n; i++) { if(height[i] >= m) { if(sa[i-1] < l1) cnt1++; if(sa[i-1] > l1) cnt2++; } else { if(sa[i-1] < l1) cnt1++; if(sa[i-1] > l1) cnt2++; if(cnt1 == 1 && cnt2 == 1) return true; cnt1 = cnt2 = 0; } } return false; } int main() { char a[5555], b[5555]; while(scanf("%s %s", &a, &b) != EOF) { l1 = strlen(a); l2 = strlen(b); int n = 0; for(int i = 0; i < l1; i++) s[n++] = a[i]; s[n++] = 'z'+1; for(int i = 0; i < l2; i++) s[n++] = b[i]; s = 0; build_sa(128, n+1); getHeight(n); int l = 1, r = 5000; int ans = -1; int len = min(l1, l2); for(int i = 1; i <= len; i++) if(ok(i, n)) { ans = i; break; } if(ans <= 0) printf("-1\n"); else printf("%d\n", ans); } return 0; }
相关文章推荐
- CF 427D Match & Catch 求最短唯一连续LCS
- CF 427D Match & Catch 求最短唯一连续LCS
- Codeforces 427D Match & Catch(后缀自动机)
- CF(427D-Match & Catch)后缀数组应用
- Codeforces 427D Match & Catch 后缀自动机 或 后缀数组
- CodeForces 427 D.Match & Catch(后缀数组)
- cf 427D Match & Catch 后缀数组
- CodeForces 427D Match & Catch 后缀数组
- CF(427D-Match & Catch)后缀数组应用
- <cf>A. Exams
- <cf>Solitaire(DFS or DP)
- hdu5442-字符串循环节&最小表示法|后缀数组(未补)|kmp+最小-Favorite Donut
- CF 433C Ryouko's Memory Note
- CF Round #218 (Div. 2) && CF 371D Vessels【并查集】
- CF 12D BALL 线段树 && 树状数组
- 实战智能推荐系统(9)-- UserCF & ItemCF
- CF 6 B - President's Office
- <为知更新>java里的throws 和 try-catch 的用法
- cf 320# "Or" Game (位运算)
- 协同过滤 CF & ALS 及在Spark上的实现