Count the string (kmp的next数组运用)

【题目来源】:https://cn.vjudge.net/problem/HDU-3336
【题意】
给出一个字符串,假设这个字符串长度为n,那么这个字符串的所有前缀字符串在原字符出现次数是多少。
举个例子:
s: “abab”
The prefixes are: “a”, “ab”, “aba”, “abab”
res=2+2+1+1=6。
【思路】
起初并没有想到用next数组去解决问题,而是想着是否可以暴力。。
大神们说可以动规,但是实力有限的我找不到对应的关系。所以只好作罢。
然后大神提醒我用next数组去解决问题。
忽然发现next数组表示的含义刚好可以用来解决这道题。
只要next数值不为0,不为-1,那么代表一定能够和前面匹配,既然能匹配,说明当前位置的字符串之前出现过,所以只要统计数值不为0和-1的次数,再加上最基础的n个字符串,什么是基础的呢?举个例子,假如字符串为ababa,那么基础的就是:
a
ab
aba
abab
ababa。
【代码】

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
const int mod=1e9+7;
const double esp=1e-5;
typedef unsigned long long ll;
typedef long long LL;
char s[200000+10];
int nexx[200000+10];
int n;
void get_next()
{
    int i=0,j;
    j=nexx[0]=-1;
    while(iwhile(-1!=j&&s[i]!=s[j]) j=nexx[j];
        nexx[++i]=++j;
    }
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        scanf("%s",s);
        get_next();
        int ans=0;
        for(int i=1; i<=n; i++)
        {
            if(nexx[i]>0)
            {
                ans++;
                if(ans>=10007)
                    ans-=10007;
            }
        }
        ans+=n;
        printf("%d\n",ans%10007);
    }
}

你可能感兴趣的:(ACM竞赛,【字符串】--KMP,ACM的进程)