[2019杭电多校第五场][hdu6629]string matching

Posted sainsist

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[2019杭电多校第五场][hdu6629]string matching相关的知识,希望对你有一定的参考价值。

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6629

题意求字符串的每个后缀与原串的最长公共前缀之和。

比赛时搞东搞西的,还搞了个后缀数组...队友一说扩展kmp我都自闭了,这不就是扩展kmp的第一步,求原串的每个后缀与原串的最长公共前缀嘛。

需要注意的就是题目准确问的是按照文中所给的代码执行需要判断几次,如果最长公共前缀等于该后缀的长度,则会判断Next[i]次(Next[i]为以i为开始的后缀与原串的最长公共前缀)。如果不等,则会判断Next[i]+1次,因为会判断一次失配。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<string>
 5 #include<algorithm>
 6 using namespace std;
 7 typedef long long ll;
 8 const int maxn = 1e6 + 10;
 9 int Next[maxn];
10 void getN(char *s1) //求子串与自身匹配
11     int i = 0, j, p, len = strlen(s1);
12     Next[0] = len;
13     while (i + 1 < len&&s1[i] == s1[i + 1])
14         i++;
15     Next[1] = i;
16     p = 1;
17     for (i = 2; i < len; i++) 
18         if (Next[i - p] + i < Next[p] + p)
19             Next[i] = Next[i - p];
20         else 
21             j = Next[p] + p - i;
22             if (j < 0)
23                 j = 0;
24             while (i + j < len&&s1[j] == s1[i + j])
25                 j++;
26             Next[i] = j;
27             p = i;
28         
29     
30 
31 char s[maxn];
32 int main() 
33     int t;
34     scanf("%d", &t);
35     while (t--) 
36         scanf("%s", s);
37         int n = strlen(s);
38         getN(s);
39         long long ans = 0;
40         for (int i = 1; i < n; ++i) 
41             if (Next[i] == n - i) ans += n - i;
42             else ans += Next[i] + 1;
43         
44         printf("%lld\n", ans);
45 
46     
47 

 

以上是关于[2019杭电多校第五场][hdu6629]string matching的主要内容,如果未能解决你的问题,请参考以下文章

[2019杭电多校第五场][hdu6624]fraction

[2019杭电多校第五场][hdu6628]permutation 1

[2019杭电多校第五场][hdu6630]permutation 2

[2019杭电多校第五场][hdu6625]three arrays(01字典树)

2019 杭电多校 第五场

2020杭电多校第五场1012-Set1