[Luogu3804]【模板】后缀自动机
2018-03-27 21:09
411 查看
luogu
请你求出\(S\)的所有出现次数不为\(1\)的子串的出现次数乘上该子串长度的最大值。
所以可以直接上基数排序求每个状态的\(endpos\)集合大小。
(我可能比较无聊建了一棵树出来跑dfs)
题目描述
给定一个只包含小写字母的字符串\(S\) ,请你求出\(S\)的所有出现次数不为\(1\)的子串的出现次数乘上该子串长度的最大值。
sol
“出现次数大于\(1\)”也就是\(endpos\)集合大小大于\(1\)。所以可以直接上基数排序求每个状态的\(endpos\)集合大小。
(我可能比较无聊建了一棵树出来跑dfs)
code
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int N = 2e6+5; int n,last=1,tot=1,tr [26],fa ,len ,sz ; int to ,nxt ,head ,cnt; char s ;long long ans; void extend(int c) { int v=last,u=++tot;last=u; len[u]=len[v]+1; while (v&&!tr[v][c]) tr[v][c]=u,v=fa[v]; if (!v) fa[u]=1; else { int x=tr[v][c]; if (len[x]==len[v]+1) fa[u]=x; else { int y=++tot; memcpy(tr[y],tr[x],sizeof(tr[y])); fa[y]=fa[x];fa[x]=fa[u]=y;len[y]=len[v]+1; while (v&&tr[v][c]==x) tr[v][c]=y,v=fa[v]; } } sz[u]=1; } void link(int u,int v){to[++cnt]=v;nxt[cnt]=head[u];head[u]=cnt;} void dfs(int u) { for (int e=head[u];e;e=nxt[e]) dfs(to[e]),sz[u]+=sz[to[e]]; if (sz[u]>1) ans=max(ans,1ll*sz[u]*len[u]); } int main() { scanf("%s",s+1);n=strlen(s+1); for (int i=1;i<=n;++i) extend(s[i]-'a'); for (int i=2;i<=tot;++i) link(fa[i],i); dfs(1);printf("%lld\n",ans); return 0; }
相关文章推荐
- 【Luogu3804】【模板】后缀自动机(后缀自动机)
- 【Luogu3804】【模板】后缀自动机(后缀自动机)
- 洛谷3804 【模板】后缀自动机
- 洛谷.3804.[模板]后缀自动机
- 回文(后缀)自动机模板
- P3804 [模板]后缀自动机
- 【hihocoder1445】后缀自动机二·重复旋律5 后缀自动机模板
- 后缀自动机模板 SAM
- hdu4622 后缀自动机 模板
- SPOJ 8222. Substrings(后缀自动机模板)
- 洛谷P3804 - 【模板】后缀自动机
- 后缀自动机,SAM,suffix automaton 模板
- hdu4622(后缀自动机模板)
- 后缀自动机模板(SPOJ1811)
- 后缀自动机模板
- 后缀自动机模板 洛谷p3804
- SAM(后缀自动机)模板
- bzoj3926: [Zjoi2015]诸神眷顾的幻想乡 广义后缀自动机模板
- SPOJ 8222. Substrings(后缀自动机模板)
- 一点对后缀自动机的理解 及模板