博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
51nod 1292 字符串中的最大值V2(后缀自动机)
阅读量:5888 次
发布时间:2019-06-19

本文共 1449 字,大约阅读时间需要 4 分钟。

题意:

有一个字符串T。字符串S的F函数值可以如下计算:F(S) = L * S在T中出现的次数(L为字符串S的长度)。求所有T的子串S中,函数F(S)的最大值。

 

题解:

求T的后缀自动机,然后所有每个后缀自动机的结点u

求出endpos[u]*maxlen[u]中的最大值即可

 

#include 
#include
#include
using namespace std;const int maxn = 1e6 + 100;const int maxn2 = maxn*2;int cnt = 1, last = 1;int endpos[maxn2], tr[maxn2][30], par[maxn2], mx[maxn2], c[maxn2], id[maxn2];int n;char s[maxn];void extend(int x){ int np = ++cnt, p = last; endpos[np] = 1; mx[np] = mx[p] + 1; last = np; while(p && !tr[p][x]) tr[p][x] = np, p = par[p]; if(!p) par[np] = 1; else { int q = tr[p][x]; if(mx[q] == mx[p]+1) par[np] = q; else { int nq = ++cnt; mx[nq] = mx[p]+1; memcpy(tr[nq], tr[q], sizeof(tr[q])); par[nq] = par[q]; par[q] = par[np] = nq; while(p && tr[p][x] == q) tr[p][x] = nq, p = par[p]; } }}void topsort(){ for(int i = 1; i <= cnt; i++) c[mx[i]]++; for(int i = 1; i <= n; i++) c[i] += c[i-1]; for(int i = 1; i <= cnt; i++) id[c[mx[i]]--] = i; for(int i = cnt; i; i--) endpos[par[id[i]]] += endpos[id[i]];}int main(){ cin>>s; n = strlen(s); for(int i = 0; i < n; i++) extend(s[i]-'a'); topsort(); endpos[0] = 0; long long ans = 0; for(int i = 1; i <= cnt; i++){ ans = max(ans, (long long)endpos[i]*mx[i]); } cout<
<

 

转载于:https://www.cnblogs.com/Saurus/p/7637747.html

你可能感兴趣的文章
[T-SQL]从变量与数据类型说起
查看>>
稀疏自动编码之反向传播算法(BP)
查看>>
二叉搜索树转换成双向链表
查看>>
WebLogic和Tomcat的区别
查看>>
java类中 获取服务器的IP 端口
查看>>
occActiveX - ActiveX with OpenCASCADE
查看>>
redmine
查看>>
css 序
查看>>
DirectshowLib摄像头拍照的”未找到可用于建立连接的介质筛选器组合“ 解决办法...
查看>>
wcf-1
查看>>
三种简单排序
查看>>
Dalvik VM和JVM的比较以及Android新的虚拟机ART
查看>>
【CSU 1803】2016
查看>>
SQLServer 批量备份与还原
查看>>
51Nod 1010 只包含因子2 3 5的数 Label:None
查看>>
Java中String和byte[]间的转换浅析
查看>>
什么是异步
查看>>
WordPress 主题切换
查看>>
cookie和session
查看>>
【java】path和classpath
查看>>