HDU 3336 Count the string KMP+DP
传送门http://acm.hdu.edu.cn/showproblem.php?pid=3336
大意:数前缀匹配了多少次如:s: "abab"
前缀为: "a", "ab", "aba", "abab" a匹配了2次,ab两次,aba一次,abab一次,故答案为6
KMP的应用。
Orz发明这个算法的人。
状态转移函数 F[i]保证了s[1 .. i]中 s[i - F[i] + 1 .. i]与 s[1 .. F[i]]是相等的。
设数组cnt:以 i结尾的串中所有前缀的计数和
则状态转移方程: cnt[i]= cnt[ F[i] ] + 1;
#include<cstdio> #include<cstring> const int mod=10007; const int MAXN=200000+10; char p[MAXN]; int f[MAXN],n,cnt[MAXN]; void getfail() { f[0]=f[1]=0; int j; for(int i=1;i<n;i++) { j=f[i]; while(j && p[i]!=p[j]) j=f[j]; if(p[i]==p[j]) j++; f[i+1]=j; } } int main() { int T; scanf("%d",&T); while(T--) { int ans=0; scanf("%d",&n); scanf("%s",p); getfail(); memset(cnt,0,sizeof(cnt)); for(int i=1;i<=n;i++) { cnt[i]=cnt[ f[i] ] +1; ans=(ans+cnt[i])%mod; } printf("%d\n",ans); } }
新 blog : www.hrwhisper.me