hdu 3336

一道KMP题目折腾了我一天了,开始的时候怎么也想不到和KMP有什么联系,看了网上的大神解法后恍然大悟,
题意是,给一串字符串,问这串字符串所有的前缀总共在这个字符串中出现了几次。
已经有了next数组,next[i]=j表示最大的j使得0~j==i-j~i,因此,对于样例abab,则有
0 1 2 3
Problem : 3336 ( Count the string )     Judge Status : Accepted
RunId : 7164232    Language : C    Author : freestyle4568
Code Render Status : Rendered By HDOJ C Code Render Version 0.01 Beta
# include<stdio.h>
# include<string.h>
int next[200003],dp[200003];
void getnext(char *str,int len)
{
    int i,j;
    for(i=1,next[0]=-1;i<=len;i++)
    {
        j=next[i-1];
        while(j>0&&str[i]!=str[j+1])
            j=next[j];
        if(str[i]==str[j+1])
            next[i]=j+1;
        else
            next[i]=0;
    }
}

void main()
{
    int i,len,sum,n;
    char str[200003];
    scanf("%d",&n);
    while(n--)
    {
        scanf("%d%s",&len,str+1);
        getnext(str,len);
        for(i=1,sum=0,dp[0]=0;i<=len;i++)
        {
            dp[i]=dp[next[i]]+1;
            sum=(sum+dp[i])%10007;
        }
        printf("%d\n",sum);
    }
}


b[ ] a b a b
p[ ] -1 -1 0 1

对于4个前缀:

a

ab

aba

abab

设dp[i]表示子串b[0~i]共含有以b[i]为结尾的前缀的数目,则以b[i]结尾的前缀数就是自己本身加上以b[p[i]]结尾的前缀数,也就是例如i=2

则有:

a

aba这两个前缀,其中a就是b[p[i]]结尾的前缀。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值