当前位置: 首页 > news >正文

后缀自动机模板

后缀自动机(SAM)模板代码

学习一周终于看懂模板

放一份代码

#include<bits/stdc++.h>
#define pb push_back
using namespace std;class SAM{
public:static const int N=2e6+10;    // 最大节点数,字符串长1e6,SAM最多2e6节点struct node{int t[26],f,len,cnt;      // t:转移边 f:后缀链接 len:最长长度 cnt:出现次数}a[N];int idx=1,lst=1;              // idx:节点总数 lst:上次插入节点vector<int> g[N];             // parent树邻接表void add(int c){int p=lst,np=++idx; lst=np;               // 创建新节点,更新lasta[np].len=a[p].len+1;                     // 新节点长度+1a[np].cnt=1;                              // 主链节点出现次数初始为1memset(a[np].t,0,sizeof a[np].t);         // 清空转移数组for(;p && !a[p].t[c];p=a[p].f) a[p].t[c]=np;  // 将没有c转移的节点指向npif(!p) a[np].f=1;                         // case1: 跳到根,后缀链接指向1else{int v=a[p].t[c];if(a[v].len==a[p].len+1) a[np].f=v;   // case2: 可直接连else{int nv=++idx;                     // case3: 需要克隆节点memcpy(a[nv].t,a[v].t,sizeof a[v].t); // 复制转移边a[nv].len=a[p].len+1;             // 克隆节点长度设为p.len+1a[nv].f=a[v].f;                   // 克隆节点后缀链接指向v的后缀链接a[nv].cnt=0;                      // 克隆节点不是主链,出现次数为0for(;p && a[p].t[c]==v;p=a[p].f) a[p].t[c]=nv; // 将指向v的转移改为指向nva[v].f=a[np].f=nv;                // 更新v和np的后缀链接}}}void dfs(int u){for(int v:g[u]) dfs(v),a[u].cnt+=a[v].cnt; // 递归子节点并累加出现次数}long long query(){for(int i=2;i<=idx;i++) g[a[i].f].pb(i);   // 建parent树,将节点挂到父节点下dfs(1);                                     // 从根开始DFS累加cntlong long ret=0;for(int i=1;i<=idx;i++) if(a[i].cnt>1) ret=max(ret,1ll*a[i].cnt*a[i].len);return ret;}
}sam;string s;int main(){cin.tie(0)->sync_with_stdio(0);cin>>s;for(char c:s) sam.add(c-'a');cout<<sam.query()<<'\n';return 0;
}/*** 解题思路:* 1. SAM每个节点代表endpos相同的子串集合,len[i]是最长长度,cnt是出现次数* 2. 插入字符时,主链节点cnt=1,克隆节点cnt=0* 3. 构建parent树(后缀链接树),DFS从叶子向上累加cnt* 4. 最终每个节点的cnt就是它代表的所有子串的出现次数* 5. 遍历所有节点,若cnt>1则更新ans = max(ans, cnt * len[i])* * 时间复杂度O(n),空间复杂度O(n*|Σ|)*/
http://www.jsqmd.com/news/715494/

相关文章:

  • memtest_vulkan:GPU显存稳定性的终极检测方案
  • Artisan咖啡烘焙软件:3步掌握专业烘焙数据可视化
  • 从零到一:用Acconeer A121雷达DIY一个智能存在检测器(含STM32源码)
  • 2. 梯度下降算法分类
  • 为什么你的Copilot Next总在关键场景“失语”?深度拆解AST解析延迟、Context Window溢出与Token预算超限的3重根因,附可复用的诊断脚本
  • 从集创赛一等奖作品看TEE的未来:RISC-V双核SoC如何解决隐私计算的性能瓶颈?
  • Win11Debloat终极指南:简单三步让你的Windows系统重获新生
  • xKV大模型压缩秘籍:跨层共享,小白也能轻松上手,收藏必备!
  • 3个高效技巧,让英雄联盟回放分析更专业
  • 终极内存检测指南:Memtest86+ 3步快速定位内存故障
  • 别再被教材骗了!SR锁存器‘不定态’的真相,我用Multisim仿真给你看
  • VS Code Copilot Next 配置即代码(IaC)实践,用YAML定义AI资源生命周期,实现毫秒级成本归因与预算硬隔离
  • GetQzonehistory终极指南:5分钟完成QQ空间历史说说完整备份
  • GPU加速全同态加密的内存优化技术解析
  • STM32 HAL库串口DMA发送卡死?手把手教你排查HAL_UART_Transmit_DMA只能发一次的坑
  • Cursor Free VIP终极指南:三步解锁AI编程助手无限功能
  • 手把手教你用Simulink给STM32生成无感方波电机代码(附避坑指南)
  • 4月28日
  • SAP ABAP开发必会:/UI2/CL_JSON序列化参数全解析,告别接口数据格式踩坑
  • Trinity多模态AI模型配置与训练优化实战指南
  • 如何禁用表格中特定列的单元格(基于首列值条件)
  • 终极指南:3步快速备份QQ空间完整历史记录,让青春记忆永不丢失
  • 三步搞定Windows和Office永久激活:KMS智能激活工具终极指南
  • 避坑指南:MMAction2训练自定义数据集时,90%的人都会遇到的5个报错及解决方法
  • Qwen3-4B-Thinking-Gemini-Distill惊艳效果:中文思考链中嵌套公式、代码块、表格渲染
  • Realistic Vision V5.1 虚拟摄影棚效果进阶:生成具有复杂光影与反射的虚拟人像
  • OBS虚拟背景插件:3步搞定专业级AI抠像,告别杂乱背景困扰
  • 构建家庭多租户AI聊天应用:儿童专属安全空间与OpenClaw集成实践
  • 如何快速解决cpp-httplib在Windows旧版本中的兼容性难题:完整指南
  • python mock