题意
我们定义2个字符串的相似度等于两个串的相同前缀的长度。例如 “abc” 同 “abd” 的相似度为2,”aaa” 同 “aaab” 的相似度为3。
给出一个字符串S,计算S同他所有后缀的相似度之和。
1 <= L <= 1000000
分析
看完题后:哈哈哈这不是sa模板题吗。花十分钟敲完后发现居然T了。。。
后来听说是exkmp的模板题,就又跑去学了一发exkmp。
直接把next数组全部加起来就好了。
一开始打exkmp的时候把pos的初值设为了1,然后就变成了大暴力。。。实际上赋为2就可以。
代码
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long LL;
const int N=1000005;
int n,next[N];
char s[N];
void get_next()
{
int mx=0,pos=0;
next[1]=n;
for (int i=2;i<=n;i++)
{
if (mx>=i) next[i]=min(mx-i+1,next[i-pos+1]);
while (i+next[i]<=n&&s[i+next[i]]==s[next[i]+1]) next[i]++;
if (i+next[i]-1>mx) mx=i+next[i]-1,pos=i;
}
}
int main()
{
scanf("%s",s+1);
n=strlen(s+1);
get_next();
LL ans=0;
for (int i=1;i<=n;i++) ans+=next[i];
printf("%lld",ans);
return 0;
}