bzoj 3620 似乎在梦中见过的样子(KMP)
【题目链接】
http://www.lydsy.com/JudgeOnline/problem.php?id=3620
【题意】
给定一个字符串,统计有多少形如A+B+A的子串,要求A>=K,B>=1。
【思路】
枚举左端点i,对字符串s[i..n]统计答案。
放个指针,然后枚举右端点j,如果指针超过长度一半则沿fail向前找,设指针为k。如果匹配则满足s[i..k]==s[j-k+1..j],最后判定一下长度限制。
【代码】
1 #include<cstdio> 2 #include<cstring> 3 using namespace std; 4 5 typedef long long ll; 6 const int N = 2e4+10; 7 8 int n,K; 9 ll ans; 10 11 int f[N]; 12 char s[N]; 13 14 void KMP(char *s) { 15 int n=strlen(s+1); 16 int j=0,now=0; 17 for(int i=2;i<=n;i++) { 18 while(j&&s[j+1]!=s[i]) j=f[j]; 19 if(s[j+1]==s[i]) j++; 20 f[i]=j; 21 22 while(now&&s[now+1]!=s[i]) now=f[now]; 23 if(s[now+1]==s[i]) now++; 24 while(2*now>=i) now=f[now]; 25 if(now>=K) ans++; 26 } 27 } 28 int main() 29 { 30 scanf("%s%d",s+2,&K); 31 int n=strlen(s+2); 32 for(int i=1;i<=n;i++) KMP(s+i); 33 printf("%lld\n",ans); 34 return 0; 35 }
posted on 2016-03-29 18:23 hahalidaxin 阅读(291) 评论(0) 编辑 收藏 举报