P3804 【模板】后缀自动机 (SAM)
空字符节点为状态1,而且这个空状态也是放在基数排序里面排序过的
还有关于clone的节点啊,要注意 他的siz一开始是设成0的
我们注意到clone节点 ++size时,没有把这个状态的siz设成1,而是0,因为这个状态是拆开的,所以后面DFS累加的时候累加上来就是原值,防止重复计算。感性理解一下把
然后
后缀自动机有两种链 ,一种是link的后缀连接,从尾一直连到头,头也就是空字串节点,从后往前走依次累加可以获得每个状态串的出现次数
一种是trans的转移连接,然后这个是从头也就是空串节点,连到尾,每次连接的新状态,长度只+1;
这两种连接是完全不同的。
链接: https://www.luogu.com.cn/problem/P3804
基数排序模拟DFS
因为maxlen大的一定在树的下面
#include<bits/stdc++.h> #define rep(i,a,n) for(int i=a;i<=n;++i) #define per(i,a,n) for(int i=n;i>=a;--i) #define pb push_back #define fi first #define se second #define io std::ios::sync_with_stdio(false) using namespace std; typedef long long ll; typedef pair<int,int> pii; const int P = 1e9+7, INF = 0x3f3f3f3f; ll gcd(ll a,ll b) { return b?gcd(b,a%b):a; } ll qpow(ll a,ll n) { ll r=1%P; for (a%=P; n; a=a*a%P,n>>=1)if(n&1)r=r*a%P; return r; } const int maxn=2e6; struct Suffix_Automata { int maxlen[maxn], trans[maxn][26], link[maxn], Size, Last; int siz[maxn]; Suffix_Automata() { Size = Last = 1; } inline void Extend(int id) { int cur = (++ Size), p; siz[Size]=1; maxlen[cur] = maxlen[Last] + 1; for (p = Last; p && !trans[p][id]; p = link[p]) trans[p][id] = cur; if (!p) link[cur] = 1; else { int q = trans[p][id]; if (maxlen[q] == maxlen[p] + 1) link[cur] = q; else { int clone = (++ Size); maxlen[clone] = maxlen[p] + 1; memcpy(trans[clone], trans[q],sizeof(trans[q])); link[clone] = link[q]; for (; p && trans[p][id] == q; p = link[p]) trans[p][id] = clone; link[cur] = link[q] = clone; } } Last = cur; } } T; int t[maxn],A[maxn]; int main() { char s[maxn]; cin>>s+1; int n=strlen(s+1); for(int i=1;i<=n;i++) { T.Extend(s[i]-'a'); } ll ans=0; for(int i=1;i<=T.Size;i++) t[T.maxlen[i]]++;//放入桶 for(int i=1;i<=n;i++) t[i]+=t[i-1];//累加排名 for(int i=1;i<=T.Size;i++) A[t[T.maxlen[i]]--]=i;//排第几的是i,同时桶-- for(int i=T.Size;i>=1;i--) { int now=A[i]; T.siz[T.link[now]]+=T.siz[now]; if(T.siz[now]>1) ans=max(ans,1ll*T.siz[now]*T.maxlen[now]); } cout<<ans<<endl; }
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从问题排查到源码分析:ActiveMQ消费端频繁日志刷屏的秘密
· 一次Java后端服务间歇性响应慢的问题排查记录
· dotnet 源代码生成器分析器入门
· ASP.NET Core 模型验证消息的本地化新姿势
· 对象命名为何需要避免'-er'和'-or'后缀
· “你见过凌晨四点的洛杉矶吗?”--《我们为什么要睡觉》
· 编程神器Trae:当我用上后,才知道自己的创造力被低估了多少
· C# 从零开始使用Layui.Wpf库开发WPF客户端
· C#/.NET/.NET Core技术前沿周刊 | 第 31 期(2025年3.17-3.23)
· 接口重试的7种常用方案!