zoukankan      html  css  js  c++  java
  • HDU 3336 扩展kmp

     题目大意:

    找到字符串中所有和前缀字符串相同的子串的个数

    对于这种前缀的问题,通常通过扩展kmp来解决

    其实吧这是我第一次做扩展kmp的题目,原来确实看过这个概念,今天突然做到,所以这个扩展kmp的模板是做到这道题直接copy的

    这里用扩展kmp很好解决问题,_next[i],表示第i位开始所能匹配到的最大公共前缀长度,比如说这个长度为4,那么说明前缀1,2,3,4都出现了一次,我们只在cnt[4]++

    那么最后从n到1,逆向更新cnt[i] += cnt[i+1]即可,最后得到cnt[i]就表示前缀长度为i的时候所能得到的相同的子串的个数

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <cstring>
     4 
     5 using namespace std;
     6 #define N 200005
     7 #define MOD 10007
     8 char s[N];
     9 int _next[N] , cnt[N];
    10 
    11 void get_next(char *T){// _next[i]: 以第i位置开始的子串 与 T的公共前缀
    12      int i,length = strlen(T);
    13      _next[0] = length;
    14      for(i = 0;i<length-1 && T[i]==T[i+1]; i++);
    15           _next[1] = i;
    16           int a = 1;
    17           for(int k = 2; k < length; k++){
    18                   int p = a+_next[a]-1, L = _next[k-a];
    19                   if( (k-1)+L >= p ){
    20                        int j = (p-k+1)>0? (p-k+1) : 0;
    21                        while(k+j<length && T[k+j]==T[j]) j++;// 枚举(p+1,length) 与(p-k+1,length) 区间比较
    22                        _next[k] = j, a = k;
    23                   }
    24                   else _next[k] = L;
    25          }
    26 }
    27 int main()
    28 {
    29    // freopen("a.in" , "r" , stdin);
    30     int T;
    31     scanf("%d" , &T);
    32     while(T--)
    33     {
    34         int n;
    35         scanf("%d%s" , &n , s);
    36         get_next(s);
    37       //  for(int i=0 ; i<n ; i++) cout<<_next[i]<<endl;
    38         memset(cnt , 0 , sizeof(cnt));
    39         for(int i=0 ; i<n ; i++) cnt[_next[i]]++;
    40         for(int i=n-1 ; i>=1 ; i--) cnt[i]+=cnt[i+1];
    41         int sum=0;
    42         for(int i=1 ; i<=n ; i++) sum = (sum+cnt[i])%MOD;
    43         printf("%d
    " , sum);
    44     }
    45     return 0;
    46 }
  • 相关阅读:
    小米面试之股票收益最大
    第三周:同时管理64位和32位版本的Python,并用Pyinstaller打包成exe
    第三周 anaconda的安装
    第二周:python实现线性回归(哑变量回归)的高效方法
    第一周:在python里调用C文件中函数
    13G:神奇的数列
    13F:图像分割
    13E:吃奶酪
    13D:拖延症
    13B:回文子串
  • 原文地址:https://www.cnblogs.com/CSU3901130321/p/4598958.html
Copyright © 2011-2022 走看看