Link
枚举左端点(i),然后计算有多少右端点满足条件。
我们可以先跑出(s_{i,n})的KMP数组,然后处理出(pos)表示(s_{i,j})的最短的并且长度(ge k)的border的右端点,然后再看是否长度(lelfloorfrac{j-i}2
floor)。
#include<cstdio>
#include<cstring>
const int N=15007;
char s[N];int next[N],pos[N];
int main()
{
int n,l,ans=0;
scanf("%s%d",s+1,&l),n=strlen(s+1);
for(int i=1;i<=n;++i)
{
next[i]=i-1,pos[i]=i;
for(int j=i+1,k=i-1;j<=n;++j)
{
while(k>=i&&s[k+1]^s[j]) k=next[k];
if(s[k+1]==s[j]) ++k;
next[j]=k,pos[j]=k<i+l-1? j:pos[k];
if(pos[j]<(i+j)>>1) ++ans;
}
}
printf("%d", ans);
}