码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2019-08-14 21:41:14      阅读:93      评论:0      收藏:0      [点我收藏+]

标签:字符串   std   杭电多校   ==   hdu   ble   clu   int   char   

题目链接: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

标签:字符串   std   杭电多校   ==   hdu   ble   clu   int   char   

原文地址:https://www.cnblogs.com/sainsist/p/11354745.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!