• HUD3336


    /*
    巧妙地使用fail数组
    根据fail数组的定义 
    fail[i] 有 长度为i的子串最长公共前后缀为fail[i]
    比如样例 fail 0 0 1 2
    那么我们维护一个ans[i]表示到i位置的时候
    前i位置子串的匹配次数
    比如 a b a 
    ans[1]=1 ans[2]=1 
    到ans[3]的时候 发现 a 又出现了一边 说明之前的a子串统计少了 
    相应的可以根据 fail找到a的位置在统计一遍就不漏了 
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define maxn 200010
    using namespace std;
    int T,an,ans[maxn],l,fail[maxn];
    char s[maxn];
    void kmp_init()
    {
        int p=0;
        for(int i=2;i<=l;i++)
          {
              while(p&&s[p+1]!=s[i])
                p=fail[p];
              if(s[p+1]==s[i])
                p++;
              fail[i]=p;
          }
    }
    int main()
    {
        scanf("%d",&T);
        while(T--)
          {
              scanf("%d",&l);
              scanf("%s",s+1);
              an=0;//初始化害死人 
              memset(ans,0,sizeof(ans));
              memset(fail,0,sizeof(fail));
            kmp_init();
            for(int i=1;i<=l;i++)
              {
                  ans[i]=1;
                  if(fail[i])//如果当前的子串存在公共前后缀 
                           //说明这个公共缀之前统计少了 
                    ans[i]+=ans[fail[i]];
                  an=(an+ans[i])%10007;
              }
            printf("%d
    ",an);
          }
    }
  • 相关阅读:
    HTML学习心得
    VS相关
    安全算法
    第三方库的编译
    C++编译问题
    GCC编译
    linux系统·用户管理
    批处理遍历并计算子文件夹下的文件数目
    [Tianchi] Repeat Buyers Prediction-Challenge the Baseline -- version 0
    win10安装cuda
  • 原文地址:https://www.cnblogs.com/yanlifneg/p/5477269.html
Copyright © 2020-2023  润新知