标签:been rri body letter mis std str cap mil
Time Limit: 4000MS | Memory Limit: 131072K | |
Total Submissions: 35607 | Accepted: 14275 | |
Case Time Limit: 1000MS |
Description
Input
Output
Sample Input
yeshowmuchiloveyoumydearmotherreallyicannotbelieveit yeaphowmuchiloveyoumydearmother
Sample Output
27
这个题目百来就是一道后缀数组的入门题,然后发现二分哈希也能做,于是就都打打。。。
后缀数组:432ms
1 #include <algorithm> 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 6 using namespace std; 7 8 const int N = 202020; 9 10 int l1, m, n, l2; 11 int c[N], x[N], y[N], sa[N], ht[N], rk[N]; 12 char s1[N], s2[N], s[N]; 13 14 inline void Get_Sa() 15 { 16 for (int i = 1; i <= n; ++i) ++c[x[i] = s[i]]; 17 for (int i = 2; i <= m; ++i) c[i] += c[i - 1]; 18 for (int i = n; i >= 1; --i) sa[c[x[i]]--] = i; 19 for (int k = 1; k <= n; k <<= 1) 20 { 21 int num = 0; 22 for (int i = n - k + 1; i <= n; ++i) y[++num] = i; 23 for (int i = 1; i <= n; ++i) if (sa[i] > k) y[++num] = sa[i] - k; 24 for (int i = 1; i <= m; ++i) c[i] = 0; 25 for (int i = 1; i <= n; ++i) ++c[x[i]]; 26 for (int i = 2; i <= m; ++i) c[i] += c[i - 1]; 27 for (int i = n; i >= 1; --i) sa[c[x[y[i]]]--] = y[i], y[i] = 0; 28 for (int i = 1; i <= n; ++i) y[i] = x[i], x[i] = 0; 29 swap(x, y), x[sa[1]] = 1, num = 1; 30 for (int i = 2; i <= n; ++i) 31 x[sa[i]] = (y[sa[i]] == y[sa[i - 1]] && y[sa[i] + k] == y[sa[i - 1] + k]) ? num : ++num; 32 if (num == n) break; m = num; 33 } 34 for (int i = 1; i <= n; ++i) rk[sa[i]] = i; 35 } 36 37 inline void Get_Ht() 38 { 39 int k = 0; 40 for (int i = 1; i <= n; ++i) 41 { 42 if (rk[i] == 1) continue; 43 if (k) --k; 44 int j = sa[rk[i] - 1]; 45 while (j + k <= n && i + k <= n 46 && s[i + k] == s[j + k]) ++k; 47 ht[rk[i]] = k; 48 } 49 } 50 51 int main() 52 { 53 while (~scanf("%s%s", s + 1, s2 + 1)) 54 { 55 int ans = -21469999; 56 l1 = strlen(s + 1); 57 l2 = strlen(s2 + 1); 58 s[l1 + 1] = ‘$‘; 59 m = 150; 60 for (int i = 1; i <= l2; ++i) 61 s[l1 + 1 + i] = s2[i]; 62 n = strlen(s + 1); 63 Get_Sa(), Get_Ht(); 64 for (int i = 1; i <= n; ++i) 65 if (sa[i - 1] >= 1 && sa[i - 1] <= l1 && sa[i] >= l1 + 1) 66 ans = max(ans, ht[i]); 67 else if (sa[i] >= 1 && sa[i] <= l1 && sa[i - 1] >= l1 + 1) 68 ans = max(ans, ht[i]); 69 // for (int i = 1; i <= n; ++i) 70 // printf("%s %d\n", s + sa[i], ht[i]); 71 printf("%d\n", ans); 72 } 73 return 0; 74 }
二分+哈希:1463ms
1 #include <algorithm> 2 #include <iostream> 3 #include <cstring> 4 #include <cstdlib> 5 #include <cstdio> 6 7 using namespace std; 8 typedef unsigned long long ull; 9 10 const ull N = 202020; 11 const ull base = 131; 12 13 int l1, l2, L, R; 14 ull bit[N], f[N], h1[N], h2[N]; 15 char s2[N], s1[N]; 16 17 inline bool good(int l) 18 { 19 int tot = 0; 20 for (int i = 1; i <= l1 - l + 1; ++i) 21 f[++tot] = h1[i + l - 1] - h1[i - 1] * bit[l]; 22 sort(f + 1, f + tot + 1); 23 for (int i = 1; i <= l2 - l + 1; ++i) 24 if (binary_search(f + 1, f + tot + 1, h2[i + l - 1] - h2[i - 1] * bit[l])) 25 return true; 26 return false; 27 } 28 29 int main() 30 { 31 for (int i = 1; i <= N - 5; ++i) bit[i] = (i == 1 ? 1 : bit[i - 1]) * base; 32 while (~scanf("%s%s", s1 + 1, s2 + 1)) 33 { 34 l1 = strlen(s1 + 1), l2 = strlen(s2 + 1); 35 for (int i = 1; i <= l1; ++i) h1[i] = h1[i - 1] * base + (s1[i] - 90); 36 for (int i = 1; i <= l2; ++i) h2[i] = h2[i - 1] * base + (s2[i] - 90); 37 L = 0, R = max(l1, l2) + 1; 38 while (L <= R) 39 { 40 int mid = (L + R) >> 1; 41 if (good(mid)) L = mid + 1; 42 else R = mid - 1; 43 } 44 printf("%d\n", R); 45 } 46 return 0; 47 }
(虽然慢一点,但哈希真的好写!!!!)
标签:been rri body letter mis std str cap mil
原文地址:https://www.cnblogs.com/yanyiming10243247/p/10094740.html