传送门
题解:
首先可以确定答案是这个串的一个border,一个border能覆盖全串的条件就是所有border包含这个位置的右端点之间的最大间距不能超过这个border的长度。
可以建立nxt树来判断,但是实际上有更加简单的做法。
设 f [ i ] f[i] f[i]表示考虑了 s [ 1 ⋯ i ] s[1\cdots i] s[1⋯i]这个串的答案,显然要么是 i i i要么是 f [ n x t [ i ] ] f[nxt[i]] f[nxt[i]],直接记录一下上一个答案在这个位置的串的位置进行比较就行了。
代码:
#include<bits/stdc++.h>
#define ll long long
#define re register
#define cs const
cs int N=5e5+7;
char s[N];
int n;
int nxt[N],f[N],las[N],h[N];
signed main(){
scanf("%s",s+1);n=strlen(s+1);
for(int re i=2,j=0;s[i];++i){
while(j&&s[i]!=s[j+1])j=nxt[j];
if(s[j+1]==s[i])++j;
nxt[i]=j;
}
f[1]=1;
for(int re i=2;s[i];++i){
f[i]=(h[f[nxt[i]]]>=i-nxt[i])?f[nxt[i]]:i;
h[f[i]]=i;
}
std::cout<<f[n]<<"\n";
return 0;
}