题目大意:给一个字符串s,计算从下标1开始一直到字符串末的子串 与 原串s的最长公共前缀lcp(如果子串的长度与lcp不相同,则需要额外的+1)。exkmp的板子题,很无聊。
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6+100;
char s[maxn];
int Next[maxn];
void get_next()
{
int i=0,po,j,len=strlen(s);
Next[0]=len;
while(i+1<len&&s[i]==s[i+1])
++i;
Next[1]=i;
po=1;
for(i=2;i<len;++i)
{
if(Next[i-po]+i<Next[po]+po)
Next[i]=Next[i-po];
else
{
j=Next[po]+po-i;
if(j<0)
j=0;
while(i+j<len&&s[j]==s[j+i])
++j;
Next[i]=j;
po=i;
}
}
}
int main()
{
int T;
cin>>T;
while(T--)
{
scanf("%s",s);
get_next();
long long int ans=0;
int len=strlen(s);
for(int i=1;i<len;++i)
{
if(i+Next[i]!=len)
++ans;
ans+=Next[i];
}
printf("%lld\n",ans);
}
return 0;
}