HDU3336 Count the string KMP+递推

题意:T组测试数据,给你一个字符串,求其前缀出现过的次数之和。例如 : abab 前缀 a 出现过两次,前缀 ab 出现过两次,前缀 aba 出现过一次,前缀 abab 出现过一次,所有前缀和为 6 ,故输出6。

思路:本题的重点在于对 next 数组的理解上,next 表示了在第 i 个字符时能匹配的最长前缀,更多关于 next 数组的含义请参考 KMP算法 的解析。对于这道题,我们只需要记录一下每个前缀所包含的次长前缀加上他本身就可以了。即递推式如下:  F[i]=F[NEXT[i]]+1  ,i(1,n) 这样我们就不会有遗漏的情况出现了。最后我们用 sum = F[1]+F[2]+……+F[n] 统计所有的前缀和即可。

代码如下:

#include <iostream>
#include <cstring>

using namespace std;

void Op_NEXT(char *p,int *NEXT){
    NEXT[0] = -1;
    int k = -1;
    int j = 0;
    int m=strlen(p);
    while(j < m){
        if(k == -1 || p[k] == p[j]){
            k++;
            j++;
            NEXT[j]=k;
        }
        else k=NEXT[k];   ///回溯
    }
}

int main()
{
    ios::sync_with_stdio(false);
    int T;
    cin>>T;
    int NEXT[200005];
    char p[200005];
    int dp[200005];
    while(T--){
        memset(dp,0,sizeof(dp));
        int n;
        cin>>n;
        cin>>p;
        Op_NEXT(p,NEXT);
        int sum=0;
        for(int i=1;i <= n;i++){
            dp[i]=dp[NEXT[i]]+1;
            sum += dp[i];
            sum %= 10007;
        }
        cout<<sum<<endl;
    }
    return 0;
}

你可能感兴趣的:(算法,KMP)