LG3804 【模板】后缀自动机
题意
给定一个只包含小写字母的字符串\(S\),
请你求出 \(S\) 的所有出现次数不为 \(1\) 的子串的出现次数乘上该子串长度的最大值。
对于\(100\%\) 的数据,\(|S| \leq 10^6\)
分析
后缀自动机和拓扑序的裸题。
对一个节点而言,其后每可转移到一个可接受的节点,标志着该节点对应的子串出现次数加1。
处理顺序需要可转移到的节点都被处理到,所以拓扑排序就好了。
时间复杂度\(O(|S|)\)
代码
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<ctime>
#include<iostream>
#include<string>
#include<vector>
#include<list>
#include<deque>
#include<stack>
#include<queue>
#include<map>
#include<set>
#include<bitset>
#include<algorithm>
#include<complex>
#define rg register
#define il inline
#pragma GCC optimize ("O3")
using namespace std;
template<class T> inline T read(T&x)
{
T data=0;
int w=1;
char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-')
w=-1;
ch=getchar();
}
while(isdigit(ch))
data=10*data+ch-'0',ch=getchar();
return x=data*w;
}
typedef long long ll;
const int INF=0x7fffffff;
const int MAXN=1e6+7;
int n;
char s[MAXN];
const int CHARSET_SIZE=26;
struct node
{
int ch[CHARSET_SIZE],fa,len;
};
struct SufAuto
{
node t[MAXN<<1];
int cnt[MAXN<<1];
int sz,root,last;
il int newnode(rg const int&x)
{
t[++sz].len=x;
return sz;
}
il void init()
{
memset(cnt,0,sizeof cnt);
sz=0;
root=last=newnode(0);
}
il void extend(rg const int&c)
{
rg int v = last,u = newnode(t[v].len + 1);
for(;v && !t[v].ch[c];v = t[v].fa)
t[v].ch[c] = u;
if(!v)
{
t[u].fa=root;
}
else
{
rg int o = t[v].ch[c];
if(t[o].len == t[v].len+1)
{
t[u].fa = o;
}
else
{
rg int n = newnode(t[v].len + 1);
copy(t[o].ch,t[o].ch+CHARSET_SIZE,t[n].ch);
t[n].fa = t[o].fa;
t[o].fa = t[u].fa = n;
for(;v && t[v].ch[c] == o;v = t[v].fa)
t[v].ch[c] = n;
}
}
cnt[u]=1;
last = u;
}
int a[MAXN<<1],c[MAXN];
il void rdxsort()
{
memset(c,0,sizeof c);
for(rg int i=1;i<=sz;++i)
++c[t[i].len];
for(rg int i=1;i<=n;++i)
c[i]+=c[i-1];
for(rg int i=sz;i>=1;--i)
a[c[t[i].len]--]=i;
}
il int solve()
{
rg ll ans=0;
for(rg int i=sz;i>=1;--i)
{
rg int p=a[i];
cnt[t[p].fa]+=cnt[p];
if(cnt[p]>1)
ans=max(ans,(ll)cnt[p]*t[p].len);
}
return ans;
}
}T;
int main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
scanf("%s",s);
n=strlen(s);
T.init();
for(rg int i=0;i<n;++i)
T.extend(s[i]-'a');
T.rdxsort();
printf("%d\n",T.solve());
// fclose(stdin);
// fclose(stdout);
return 0;
}
LG3804 【模板】后缀自动机的更多相关文章
- [模板] 后缀自动机&&后缀树
后缀自动机 后缀自动机是一种确定性有限状态自动机, 它可以接收字符串\(s\)的所有后缀. 构造, 性质 翻译自毛子俄罗斯神仙的博客, 讲的很好 后缀自动机详解 - DZYO的博客 - CSDN博客 ...
- Luogu3804:[模板]后缀自动机
题面 luogu Sol \(sam\)然后树形\(DP\) 当时还不会拓扑排序的我 # include <bits/stdc++.h> # define IL inline # defi ...
- 洛谷 P3804 [模板] 后缀自动机
题目:https://www.luogu.org/problemnew/show/P3804 模仿了一篇题解,感觉很好写啊. 代码如下: #include<cstdio> #include ...
- SPOJ LCS Longest Common Substring 和 LG3804 【模板】后缀自动机
Longest Common Substring 给两个串A和B,求这两个串的最长公共子串. no more than 250000 分析 参照OI wiki. 给定两个字符串 S 和 T ,求出最长 ...
- 【Luogu3804】【模板】后缀自动机(后缀自动机)
[Luogu3804][模板]后缀自动机(后缀自动机) 题面 洛谷 题解 一个串的出现次数等于\(right/endpos\)集合的大小 而这个集合的大小等于所有\(parent\)树上儿子的大小 这 ...
- 字符串数据结构模板/题单(后缀数组,后缀自动机,LCP,后缀平衡树,回文自动机)
模板 后缀数组 #include<bits/stdc++.h> #define R register int using namespace std; const int N=1e6+9; ...
- P3804 【模板】后缀自动机
P3804 [模板]后缀自动机 后缀自动机模板 详情可见luogu题解板块 #include<iostream> #include<cstdio> #include<cs ...
- 2018.07.17 后缀自动机模板(SAM)
洛谷传送门 这是一道后缀自动机的模板题,这道题让我切身体会到了后缀自动机的方便与好写. 代码如下: #include<bits/stdc++.h> #define N 2000005 #d ...
- 牛客网 桂林电子科技大学第三届ACM程序设计竞赛 A.串串-后缀自动机模板题
链接:https://ac.nowcoder.com/acm/contest/558/A来源:牛客网 A.串串 小猫在研究字符串. 小猫在研究字串. 给定一个长度为N的字符串S,问所有它的子串Sl…r ...
随机推荐
- Confluence 6 配置 LDAP 连接池
当 LDAP 连接池被启用后,LDAP 目录服务器将会维护一个连接池同时当必要的时候指派他们.当一个连接关闭后,这个连接将会放回到连接池中供以后进行使用.这种设置将会有效的提高系统性能. 希望配置 L ...
- PHP函数笔记
一.函数(Function) 1.什么是函数:封装的,可以重复使用的 完成特定功能的代码段. 2.分类 (1)系统函数 (2)自定义函数 3.自定义函数 ...
- from * import *(ImportError: No module named *)为什么报错没有这个目录
先说下from * import * 的原理:比如有路径D:\fanbingbing\ai\wo.py这么一个文件,而现在你在D:\fanbingbing\buai\ni.py(别介意这么比喻..(⊙ ...
- 常用Java字符API
- iterator not dereferencable问题
STL中的迭代器总是出现各种问题,这个是我在打表达式求值时碰到的... 综合网上的答案,一般来说有两种情况: 第一:访问了非法位置. 一般来说可能在queue为空时取front(),rear(),或者 ...
- POJ-3635 Full Tank? (记忆化广搜)
Description After going through the receipts from your car trip through Europe this summer, you real ...
- 4. Median of Two Sorted Arrays *HARD* -- 查找两个排序数组的中位数(寻找两个排序数组中第k大的数)
There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median of the two ...
- elment-ui table组件 -- 远程筛选排序
elment-ui table组件 -- 远程筛选排序 基于 elment-ui table组件 开发,主要请求后台实现筛选 排序的功能. 需求 排序 筛选 是对后台整个数据进行操作,而不是对当前页面 ...
- SVM学习(五):松弛变量与惩罚因子
https://blog.csdn.net/qll125596718/article/details/6910921 1.松弛变量 现在我们已经把一个本来线性不可分的文本分类问题,通过映射到高维空间而 ...
- gitlab永久设置密码
在 .gitconfig 文件中加入: [credential] helper = store .git-credentials close address