[超意识流]可意会的后缀自动机

笔记稍后补上,先看图

struct SAM{
    int tot;
    char str[MAXN];
    int maxlen[MAXN],minlen[MAXN],trans[MAXN][26],slink[MAXN];
    void init(){
        tot=1;
        maxlen[tot]=minlen[tot]=slink[tot]=0;
        rep(i,0,25) trans[tot][i]=0;
    }
    int node(int mx,int mn,int from,int _slink){
        ++tot;
        maxlen[tot]=mx;
        minlen[tot]=mn;
        slink[tot]=_slink;
        rep(i,0,25) trans[tot][i]=trans[from][i];
        return tot;
    }
    int add(char ch,int u){
        int c=ch-'a',v=u;
        int z=node(maxlen[u]+1,-1,0,0);
        while(v&&trans[v][c]==0){
            trans[v][c]=z;
            v=slink[v];
        }
        if(v==0){
            minlen[z]=1;
            slink[z]=1;
            return z;
        }
        int x=trans[v][c];
        if(maxlen[v]+1==maxlen[x]){
            minlen[z]=maxlen[x]+1;
            slink[z]=x;
            return z;
        }
        int y=node(maxlen[v]+1,-1,x,slink[x]);
        slink[z]=slink[x]=y;
        minlen[x]=minlen[z]=maxlen[y]+1;
        while(v&&trans[v][c]==x){
            trans[v][c]=y;
            v=slink[v];
        }
        minlen[y]=maxlen[slink[y]]+1;
        return z;
    }
    void build(){
        int t=tot;
        int len=strlen(str+1);
        rep(i,1,len) t=add(str[i],t);
    }
}sam;

猜你喜欢

转载自www.cnblogs.com/caturra/p/9559406.html