hdu 3336 Count the string(KMP+dp)

来源:互联网 发布:普通增值税发票软件 编辑:程序博客网 时间:2024/06/06 16:32

利用next数组的性质。

next[i]表示1~i-1的后缀与1~next[i]-1前缀匹配。此前缀为可以匹配的最长前缀。


dp[i]表示以i结尾的不同前缀的数量。

转移方程就为dp[i]=dp[next[i]]+1;(加了0~si这个新前缀)

由于next的性质,包含的以 i 结尾的不同前缀的数量除了s0~si其他全在s0~snext[i]中出现过。

因为这是最长的匹配,再往前就不是前缀了。


附上代码喵:

#include<stdio.h>#include<string.h>const int maxn=201000;const int M=10007;typedef long long ll;char s[maxn];int next[maxn];int dp[maxn];//dp[i]表示以i结尾的不同前缀的数量。void getnext(int l){memset(next,0,sizeof(next));int j=-1,k=0;next[0]=-1;while(k<l){if(j==-1||s[j]==s[k]){j++;k++;next[k]=j;}elsej=next[j];}}int main(){int t,n;scanf("%d",&t);while(t--){scanf("%d%s",&n,s);getnext(n);memset(dp,0,sizeof(dp));int sum=0;for(int i=0;i<n;i++){dp[i+1]=(dp[next[i+1]]+1)%M;sum+=dp[i+1];sum%=M;}printf("%d\n",sum);}return 0;}





0 0
原创粉丝点击