zoukankan      html  css  js  c++  java
  • 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);
          }
    }
  • 相关阅读:
    新·刷题记录【争取认真来做】
    Codeforces 235D Graph Game
    Codeforces 235B Let's Play Osu!
    Codeforces 235E Number Challenge
    Codeforces 235C Cyclical Quest
    AHOI2017游记
    bzoj4826: [Hnoi2017]影魔
    大数分解模板
    A new start
    0712
  • 原文地址:https://www.cnblogs.com/yanlifneg/p/5477269.html
Copyright © 2011-2022 走看看