Count the string kmp

Posted bxd123

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Count the string kmp相关的知识,希望对你有一定的参考价值。

  

问题描述
众所周知,aekdycoin擅长字符串问题和数论问题。当给定一个字符串s时,我们可以写下该字符串的所有非空前缀。例如:
S:“ABAB”
前缀是:“A”、“AB”、“ABA”、“ABAB”
对于每个前缀,我们可以计算它在s中匹配的次数,因此我们可以看到前缀“a”匹配两次,“ab”也匹配两次,“ab a”匹配一次,“ab ab”匹配一次。现在,您需要计算所有前缀的匹配时间之和。对于“abab”,它是2+2+1+1=6。
答案可能非常大,因此输出答案mod 10007。


输入
第一行是一个整数t,表示测试用例的数量。对于每种情况,第一行是一个整数n(1<=n<=200000),它是字符串s的长度。后面的一行给出字符串s。字符串中的字符都是小写字母。


产量
对于每种情况,只输出一个数字:s mod 10007所有前缀的匹配时间总和。

 

对s进行lens次的分割  然后不断kmp  但是超时了

技术图片
#include<bits/stdc++.h>
using namespace std;
//input
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i>=(b);i--)
#define RI(n) scanf("%d",&(n))
#define RII(n,m) scanf("%d%d",&n,&m);
#define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
#define RS(s) scanf("%s",s);
#define ll long long
#define inf 0x3f3f3f3f
#define REP(i,N)  for(int i=0;i<(N);i++)
#define CLR(A,v)  memset(A,v,sizeof A)
//////////////////////////////////
#define N 200000+5
#define mod 10007
string s,p;
int ans;
int lens,lenp;
int nex[N];
void getnext()
{
    nex[0]=-1;
    int k=-1,j=0;
    while(j<lenp-1)
    {
        if(k==-1||p[j]==p[k])
            nex[++j]=++k;
        else k=nex[k];
    }
}

int kmp()
{
    int j=0,i=0;
    while(i<lens&&j<lenp)
    {
        if(s[i]==p[j]||j==-1)
        {
            i++;
            j++;
        }
        else j=nex[j];
        if(j==lenp)
        {
            ans++;j=0;
        }
    }
}

int main()
{
    int cas;
    RI(cas);
    while(cas--)
    {
        RI(lens);
        ans=0;
        cin>>s;
        for(lenp=1;lenp<=lens;lenp++)
        {
            p=s.substr(0,lenp);
            getnext();
            kmp();
        }
         cout<<ans<<endl;
    }
    return 0;
}
View Code

显然都200000了  必然会超时的

 

以上是关于Count the string kmp的主要内容,如果未能解决你的问题,请参考以下文章

HDU 3336 Count the string (kmp+dp)

HDU Count the string (KMP)

Count the string (KMP+DP)

Count the string kmp

hdu 3336 Count the string (KMP+DP)

[HDU3336]Count the string(KMP+DP)