HDU 3336 Count the string(KMP)

Topic links: http://acm.hdu.edu.cn/showproblem.php?pid=3336

Problem-solving ideas:

First original array configuration mismatch Array

fail [i] denotes 0 ~ i-1 before the longest common suffix

First, we shilling ans = len, is the first to add each prefix itself

We can guarantee that will not coincide with those obtained in the suffix array fail, otherwise called the prefix.

Next traversal fail [2] ~ fail [len]

For each of us fail to find all i-1 to the end of the suffix suffix

First, the current fail [i] is not 0, then there must be 0 ~ x == i-1-x ~ i-1

And we ensure that no suffix was previously counted, because before i-1 had not ending with the suffix

We all want to get to i-1 suffix of how to do, is to go back along the side of the mismatch, see fail [fail [i]] is greater than 0, greater than 0 can prove from the i-1-x ~ i- then cutting out a 1 i-1 at the end of the shorter extension, look fail [fail [fail [i]]] until this value is not greater than zero.

Code:

#include<cstdio>
#include<cstring>
#include<algorithm>
#define mod 10007

using namespace std;

const int N = 2e5+5;

char s[N];
int fail[N];

void kmp(int len)
{
    fail[0] = -1;
    for (int i=0,j=-1;i<len;){
        if (j==-1||s[i]==s[j]){
            i++;j++;
            fail[i] = j;
        }
        else j = fail[j];
    }

    int ans = len%mod;
    for (int i=2;i<=len;i++){
        if (fail[i]>0) ans++;
        int now = fail[i];
        while (fail[now]>0){
            ans++;
            now = fail[now];
        }
    }
    printf("%d\n",ans%mod);
}

int main()
{
    int T;
    scanf("%d",&T);
    while (T--){
        int n;
        scanf("%d",&n);
        scanf("%s",s);
        kmp(n);
    }
    return 0;
}

I do not know think is not complicated, if later felt easier way from another title to change it back

Guess you like

Origin blog.csdn.net/weixin_43768644/article/details/94546846