SAM模板
#include <iostream> #include <cstdio> using namespace std; const int N=1e6+1; struct Node { int len,link,sz;//len是right集的最大值,link是parent树上的父亲,sz是...后缀大小,这里无用 int c[26];//类似字典树的东西 }s[2*N]; int scnt,last; void Extend(char c) { int cur=++scnt;//当前新加点的位置cur s[cur].len=s[last].len+1;s[cur].sz=1;//right集+1 int p=last; for (;p!=-1&&!s[p].c[c-'a'];p=s[p].link) s[p].c[c-'a']=cur;//在parent树向上寻找已包含其他串的点 last=cur; if (p==-1) {//跑到根节点退出 s[cur].link=0; return; } int q=s[p].c[c-'a'];//找到的被包含的点 if (s[q].len==s[p].len+1) {//如果right集合真包含也行 s[cur].link=q; return; } //否则建立克隆节点 int clone=++scnt;//节点位置 s[clone]=s[q]; s[clone].sz=0;s[clone].len=s[p].len+1;//建立了一个满足真包含p的节点 s[cur].link=s[q].link=clone;//两者都被真包含 for (;p!=-1&&s[p].c[c-'a']==q;p=s[p].link) s[p].c[c-'a']=clone;//更新与q相连的点 } //估计错误百出,本来就不会SAM
在日渐沉没的世界里,我发现了你。