HDU 4763 Theme Section
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 4763 Theme Section相关的知识,希望对你有一定的参考价值。
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4763
-------------------------------------------------------------------------------------------
数据范围卡了$SA$但数据却没能构造到卡一些理论复杂度更高的方法
这里说一下比较靠谱的$exkmp$的做法
根据$exkmp$的$next$数组定义
我们可以用$O(n)$的时间得到一个后缀与整个串的最长公共前缀的长度
然后我们就可以根据$next[n - i + 1]$与$i$是否相等判断前后缀是否相等
而对于中间的部分 我们知道如果 $next[i + 1]$到$next[n - i]$中的最大值不小于$i$
那么$i$即为一个可行解
但此处直接扫描的话复杂度显然不够 再观察可以发现如果我们把答案从大到小枚举
那么这个取最大值区间的范围是逐渐增大的 于是均摊下来的复杂度还是线性的
1 #include <cstdio> 2 #include <cstring> 3 #include <cmath> 4 #include <algorithm> 5 using namespace std; 6 const int N = 1e6 + 10; 7 char s[N]; 8 int nexte[N]; 9 int t, ans, n; 10 int main() 11 { 12 scanf("%d", &t); 13 while(t--) 14 { 15 scanf("%s", s + 1); 16 n = strlen(s + 1); 17 if(n <= 2) 18 { 19 puts("0"); 20 continue; 21 } 22 nexte[1] = n; 23 int id = 2, p = 1; 24 while(p < n && s[p] == s[p + 1]) 25 ++p; 26 nexte[2] = p - 1; 27 for(int i = 3; i <= n; ++i) 28 { 29 int l = nexte[i - id + 1]; 30 if(i + l <= p) 31 nexte[i] = l; 32 else 33 { 34 p = max(p, i - 1); 35 while(p < n && s[p - i + 2] == s[p + 1]) 36 ++p; 37 nexte[i] = p - i + 1; 38 id = i; 39 } 40 } 41 int len = n / 3, mx = 0; 42 for(int i = len + 1; i <= n - len; ++i) 43 mx = max(mx, nexte[i]); 44 ans = 0; 45 for(int i = len; i; --i) 46 { 47 if(nexte[n - i + 1] == i && mx >= i) 48 { 49 ans = i; 50 break; 51 } 52 mx = max(mx, nexte[i]); 53 mx = max(mx, nexte[n - i + 1]); 54 } 55 printf("%d\n", ans); 56 } 57 return 0; 58 }
以上是关于HDU 4763 Theme Section的主要内容,如果未能解决你的问题,请参考以下文章