【51nod1292】字符串中的最大值

  • 本文为博主原创,未经许可不得转载

这题是后缀自动机一眼题,但是我们有更简洁的方法解决它

我们回想kmp算法,一个串在进行自我匹配时j指针所在的位置正好是长度为j的前缀,每次匹配长度为j的前缀都被匹配上了一次

我们只需要记录每次j指针的位置,然后cnt[j]++就能统计次数

博主刚开始就是这么干的,结果样例都过不了

经过手玩推导,博主发现在长度为j的前缀被匹配到的同时,可能出现长度小于j的前缀也匹配到了的情况

博主不会处理这种情况于是去翻大佬题解

在某篇博客中提到了一个叫做next树的东西,就像AC自动机fail树一样,kmp中的next指针也形成了一棵树

所以要按照顺序沿着next树更新cnt数组,长知识了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include<bits/stdc++.h>
#define FILE "read"
#define MAXN 1000010
#define cmax(a,b) a=max(a,b)
#define cmin(a,b) a=min(a,b)
using namespace std;
typedef long long ll;
int n,pre[MAXN],cnt[MAXN];
char ch[MAXN];
int main(){
freopen(FILE".in","r",stdin);
freopen(FILE".out","w",stdout);
scanf("%s",ch+1); n=strlen(ch+1); ll ans=0;
for(int i=2,j=0;i<=n;++i){
while(ch[j+1]!=ch[i]&&j) j=pre[j];
if(ch[j+1]==ch[i]) ++j; pre[i]=j; cnt[j]++;
}
for(int i=n;i;--i){
cmax(ans,(ll)(cnt[i]+1)*i);
cnt[pre[i]]+=cnt[i];
}
printf("%lld\n",ans);
return 0;
}
文章目录
,