[bzoj3620][kmp]It seems like I have seen it in a dream

Description

"Madoka, don't trust QB!" With Homura's disappointed shout, Madoka signed a contract with QB. This was
a nightmare for Modoka and what happened in the last reincarnation. To make this time Madoka no longer with QB signed a contract, and Homura decided to solve
QB on the first day of school. However, QB also has many doubles (but the plot in Chapter 8 shows that it may also be infinitely reborn), however, determined Homura won't give up - she decides to
destroy everything that could be a QB. Now, she has sensed the state of the neighborhood, and turned it into a string of length n for you, who learned OI. Now you From her words, we know
that all strings similar to A+B+A are QB or its stand-in, and len(A)>=k, len(B)>=1
(different substrings with the same properties) Count different substrings, substrings with the same position but different splits count as the same substring), then you have to tell Homura the answer as soon as possible
- the number of QB and its doubles.

Input

The first line is a string, the second line is a number k

Output

There is only one number ans in one line, indicating the number of QB and its substitutes

Sample Input

【Sample input 1】

aaaaa

1

【Sample input 2】

abcabcabc

2

Sample Output

[Sample output 1]

6

[Sample output 2]

8

HINT

For 100% data: n<=15000 , k<=100, and the character set is all lowercase letters

answer

I really didn't expect N^2 to pass 2333 in this question... I
was thinking about nlogn first and found that I just didn't move, and then I realized that N^2 could pass. .
You enumerate each starting point and run KMP again, and record a go[i] to indicate that this point can satisfy >=K and has the smallest length. If it does not exist, INF
and scan it again. .

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
using namespace std;
int p[16010],go[16010],K,ans,tmp;
char ch[16010];
int main()
{
    scanf("%s",ch+1);int n=strlen(ch+1);
    scanf("%d",&K);tmp=0;
    go[0]=999999999;
    for(int i=1;i<=n;i++)
    {
        p[i]=0;go[i]=999999999;
        for(int j=i+1;j<=n;j++)
        {
            int u=p[j-1];
            while(u && ch[u+1+tmp]!=ch[j])u=p[u+tmp];
            if(ch[u+1+tmp]==ch[j])u++;
            p[j]=u;
            go[j]=go[u+tmp];
            if(p[j]>=K)go[j]=min(go[j],p[j]);
            if(go[j]>=K && 2*go[j]<=(j-i+1)-1)ans++;
        }
        tmp++;
    }
    printf("%d\n",ans);
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324734137&siteId=291194637