• [2019杭电多校第五场][hdu6629]string matching(扩展kmp)


    题目链接: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
    ", ans);
    45 
    46     }
    47 }
  • 相关阅读:
    行定位符、单词定界符实例用法
    什么是正则表达式?
    PHP正则表达式语法汇总
    PDO中的存储过程的详细介绍
    PDO中的事务处理具体介绍
    PDO中错误处理的方法
    PDO中错误处理的方法
    使用默认模式-PDO::ERRMODE_SILENT
    PDO中执行SQL语句的三种方法
    使用默认模式-PDO::ERRMODE_SILENT
  • 原文地址:https://www.cnblogs.com/sainsist/p/11354745.html
Copyright © 2020-2023  润新知