【ybtoj 高效进阶 2.3】 【kmp】 子串拆分
题目
解题思路
要求所有满足形如A+B+A的所有子串
先枚举左边界l
跑一遍l到len的kmp
然后枚举右边界
找到公共前后缀
如果其长度*2大于等于当前子串的长度
就向前取next的值
最后判断其长度是否大于等于k
满足即累加
代码
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
char x[20020],s[20020];
int len,l,ans,m;
int next[20020];
int main()
{
scanf("%s",x+1);
len=strlen(x+1);
scanf("%d",&m);
for (int i=1;i<=len;i++) //枚举左边界
{
memset(s,0,sizeof(s));
memset(next,0,sizeof(next)); //记得清0
for (int j=1;j<=len-i+1;j++)
s[j]=x[j+i-1];
l=len-i+1;
int k=0;
for (int j=1;j<l;j++)
{
while (k>0&&s[j+1]!=s[k+1]) k=next[k];
if (s[j+1]==s[k+1]) k++;
next[j+1]=k;
} //求出next
k=0;
for (int j=0;j<=l;j++) //枚举右边界
{
while (k>0&&s[j+1]!=s[k+1]) k=next[k];
if (s[j+1]==s[k+1]) k++;
while (k*2>=j+1) k=next[k]; //保证B不是空串
if (k>=m) ans++; //满足条件累加
}
}
printf("%d\n",ans);
return 0;
}