zoukankan      html  css  js  c++  java
  • [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 }
  • 相关阅读:
    三:oracle练习
    二:SQL 函数
    一:SQL基本语法
    生产者与消费者模式(理解) 进程间通信之消息队列编程
    C语言
    前端面试:基础javascript篇(二)
    Koa入门和源码分析
    前端面试:基础javascript篇(一)
    前端面试题(二)
    C复习
  • 原文地址:https://www.cnblogs.com/sainsist/p/11354745.html
Copyright © 2011-2022 走看看