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 
View Code

 

posted @ 2018-08-15 21:06  Vagari  阅读(230)  评论(0编辑  收藏  举报