Loading [MathJax]/jax/output/CommonHTML/jax.js

Gym101821D Search Engine

String Cheese

小F有一个字符串 S 和一个初始为空的字符串 T ,以及一个初始为 0 的变量 c 。他会不断重复进行以下两步操作,直到 T 的长度超过 S 时结束:

  1. T 的开头或者结尾任意添加一个字符。

  2. TS 中作为子串出现了 k 次,则执行操作 c=c+k

小F想知道,如果合理地进行第一步操作,操作结束时 c 所能达到的最大值是多少。

对于所有数据保证 1|S|5×105 ,且 S 中仅包含小写字母。

题解

首先我们可以限制任何时刻T都要是S的子串,然后设dp(T)表示从串T开局的最大答案。任意实现一个能子串判重的算法就可以暴力转移做到O(n2σ)。后面大写字母一律代表某字符串,小写字母一律
代表某字符。

构建出S的后缀自动机。可以证明如果right(aX)=right(X)则对于任意Y都有right(aXY)=right(XY),所以对于当前串T如果存在a使得right(T)=right(aT)则一定存在一种最优方案第一步选择在左边添加a,而这也就是后缀自动机上节点代表的最长串。所以我们的
转移边有两种,一种是向后加字符,可以沿着后缀自动机走;一种是向前加字符,可以沿着parent link走,每次走到一个点直接扩展到最大长度就行了,这两者都可以按拓扑序倒序算dp值,复杂度就是构建后缀自动机的复杂度。

CO int N=1e6;
int last=1,tot=1;
array<int,26> ch[N];
int fa[N],len[N],siz[N];
void extend(int c){
int x=last,cur=last=++tot;
len[cur]=len[x]+1,siz[cur]=1;
for(;x and !ch[x][c];x=fa[x]) ch[x][c]=cur;
if(!x) {fa[cur]=1; return;}
int y=ch[x][c];
if(len[y]==len[x]+1) {fa[cur]=y; return;}
int clone=++tot;
ch[clone]=ch[y],fa[clone]=fa[y],len[clone]=len[x]+1;
fa[cur]=fa[y]=clone;
for(;ch[x][c]==y;x=fa[x]) ch[x][c]=clone;
}
char str[N];
int cnt[N],ord[N];
int64 dp[N];
int main(){
scanf("%s",str+1);
int n=strlen(str+1);
for(int i=1;i<=n;++i) extend(str[i]-'a');
for(int i=1;i<=tot;++i) ++cnt[len[i]];
for(int i=1;i<=n;++i) cnt[i]+=cnt[i-1];
for(int i=1;i<=tot;++i) ord[cnt[len[i]]--]=i;
for(int i=tot;i>=2;--i) siz[fa[ord[i]]]+=siz[ord[i]];
dp[1]=0;
for(int i=1;i<=tot;++i){
int x=ord[i];
dp[x]=max(dp[x],dp[fa[x]]+(int64)(len[x]-len[fa[x]])*siz[x]);
for(int c=0;c<26;++c)if(ch[x][c])
dp[ch[x][c]]=max(dp[ch[x][c]],dp[x]+(int64)(len[ch[x][c]]-len[x])*siz[ch[x][c]]);
}
write(dp[last],'\n');
return 0;
}

posted on   autoint  阅读(139)  评论(0编辑  收藏  举报

编辑推荐:
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· dotnet 源代码生成器分析器入门
· ASP.NET Core 模型验证消息的本地化新姿势
阅读排行:
· ThreeJs-16智慧城市项目(重磅以及未来发展ai)
· .NET 原生驾驭 AI 新基建实战系列(一):向量数据库的应用与畅想
· Ai满嘴顺口溜,想考研?浪费我几个小时
· Browser-use 详细介绍&使用文档
· 软件产品开发中常见的10个问题及处理方法
历史上的今天:
2019-08-02 test20190802 夏令营NOIP训练18

导航

点击右上角即可分享
微信分享提示